master
lion 2 days ago
parent 2222957812
commit eb7db42e92

@ -7,13 +7,6 @@
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= webpackConfig.name %></title>
<script>
window._AMapSecurityConfig = {
securityJsCode: '33028b966409f0eee8dd3e5febd190b8',
}
</script>
<script type="text/javascript" src='https://webapi.amap.com/maps?v=1.4.11&key=e8f1e5a1f7fc7e24e12ea2a81c07826a&plugin=AMap.PlaceSearch'></script>
<script src="https://webapi.amap.com/ui/1.0/main.js?v=1.0.11"></script>
<script src="/filejs/FileSaver.min.js"></script>
<script src="/filejs/xlsx.full.min.js"></script>
</head>

@ -0,0 +1,265 @@
<template>
<div class="tdt-picker">
<el-input
class="tdt-picker-trigger"
:value="displayValue"
readonly
placeholder="请选择签到地点"
@click.native="openDialog"
>
<el-button slot="append" icon="el-icon-location" @click="openDialog"></el-button>
</el-input>
<el-dialog
title="在地图上选择签到地点"
:visible.sync="dialogVisible"
width="90%"
top="4vh"
append-to-body
:close-on-click-modal="false"
@close="clearSearch"
@opened="onDialogOpened"
@closed="onDialogClosed"
>
<div class="tdt-picker-toolbar">
<div class="tdt-picker-search-wrap">
<el-input
v-model="keyword"
class="tdt-picker-search"
clearable
placeholder="搜索地址或地点"
@input="onKeywordInput"
@keyup.enter.native="search"
>
<el-button slot="append" icon="el-icon-search" :loading="searching" @click="search"></el-button>
</el-input>
<div v-if="searchResults.length" class="tdt-picker-results">
<div
v-for="(item, index) in searchResults"
:key="`${item.lon || item.lonlat}-${index}`"
class="tdt-picker-result"
@click="chooseSearchResult(item)"
>
<div class="tdt-picker-result-name">{{ item.name || item.address }}</div>
<div class="tdt-picker-result-address">{{ item.address || item.name }}</div>
</div>
</div>
</div>
<el-button type="success" icon="el-icon-location-information" :loading="locating" @click="locate"></el-button>
<span class="tdt-picker-current">{{ draft.address || '点击地图选择位置' }}</span>
</div>
<div ref="map" class="tdt-picker-map"></div>
<span slot="footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" :disabled="!hasCoordinates || !draft.address" @click="confirm"></el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import {
loadTianDiTu,
gcj02ToWgs84,
wgs84ToGcj02,
formatCoordinate,
reverseGeocode,
searchTianDiTu
} from '@/utils/tianditu'
const DEFAULT_CENTER = [120.585315, 31.298886]
export default {
name: 'TianDiTuPicker',
props: {
value: { type: Array, default: () => [] },
zoom: { type: Number, default: 11 }
},
data() {
return {
map: null,
marker: null,
dialogVisible: false,
keyword: '',
searching: false,
locating: false,
searchTimer: null,
searchVersion: 0,
searchResults: [],
draft: { lng: '', lat: '', address: '' }
}
},
beforeDestroy() {
this.clearSearch()
},
computed: {
hasCoordinates() {
return Number.isFinite(Number(this.draft.lng)) && Number.isFinite(Number(this.draft.lat)) && !(Number(this.draft.lng) === 0 && Number(this.draft.lat) === 0)
},
displayValue() {
if (this.value && this.value[2]) return this.value[2]
return ''
}
},
watch: {
value: {
deep: true,
handler(value) {
if (this.map && value && value.length >= 2) {
const wgs = gcj02ToWgs84(value[0], value[1])
this.setDraft(wgs[0], wgs[1], value[2])
this.setMarker(wgs[0], wgs[1], false)
}
}
}
},
methods: {
clearSearch() {
clearTimeout(this.searchTimer)
this.searchVersion += 1
this.searching = false
this.searchResults = []
},
onKeywordInput() {
this.clearSearch()
if (!this.keyword.trim()) return
this.searchTimer = setTimeout(() => this.search(false), 350)
},
openDialog() {
this.dialogVisible = true
this.searchResults = []
this.keyword = ''
if (this.value && this.value.length >= 2) {
const wgs = gcj02ToWgs84(this.value[0], this.value[1])
this.setDraft(wgs[0], wgs[1], this.value[2])
} else {
this.setDraft('', '', '')
}
},
async onDialogOpened() {
try {
const T = await loadTianDiTu()
const center = this.draft.lng && this.draft.lat ? [this.draft.lng, this.draft.lat] : DEFAULT_CENTER
this.map = new T.Map(this.$refs.map)
this.map.centerAndZoom(new T.LngLat(center[0], center[1]), this.zoom)
this.map.addEventListener('click', this.onMapClick)
if (this.draft.lng && this.draft.lat) this.setMarker(this.draft.lng, this.draft.lat, false)
} catch (error) {
this.$message.error(error.message || '天地图加载失败')
}
},
onDialogClosed() {
if (this.map) {
this.map.clearOverLays()
this.map = null
this.marker = null
}
},
async search(showMessage = true) {
clearTimeout(this.searchTimer)
if (!this.keyword.trim()) return showMessage && this.$message.warning('请输入搜索地址或地点')
const version = ++this.searchVersion
this.searching = true
try {
const results = await searchTianDiTu(this.keyword.trim())
if (version !== this.searchVersion || !this.dialogVisible) return
this.searchResults = results
if (showMessage && !results.length) this.$message.info('没有找到相关地点')
} catch (error) {
if (version === this.searchVersion && this.dialogVisible) this.$message.error(error.message || '搜索失败,请稍后重试')
} finally {
if (version === this.searchVersion) this.searching = false
}
},
chooseSearchResult(item) {
const coords = String(item.lonlat || item.lon || '').split(',')
if (coords.length < 2) return
const lng = Number(coords[0])
const lat = Number(coords[1])
if (!Number.isFinite(lng) || !Number.isFinite(lat)) return
this.setDraft(lng, lat, item.address || item.name || '')
this.clearSearch()
this.keyword = item.name || item.address || ''
if (this.map) {
this.map.centerAndZoom(new window.T.LngLat(lng, lat), 16)
this.setMarker(lng, lat, false)
}
},
locate() {
if (!navigator.geolocation) return this.$message.warning('当前浏览器不支持定位')
this.locating = true
navigator.geolocation.getCurrentPosition(async position => {
const lng = position.coords.longitude
const lat = position.coords.latitude
this.setDraft(lng, lat, '')
if (this.map) {
this.map.centerAndZoom(new window.T.LngLat(lng, lat), 16)
this.setMarker(lng, lat, true)
}
try {
const address = await reverseGeocode(lng, lat)
if (address) this.setDraft(lng, lat, address)
} catch (error) {
this.setDraft(lng, lat, '')
this.$message.warning('当前位置地址解析失败,请稍后重试')
}
this.locating = false
}, error => {
this.locating = false
this.$message.error(error.code === 1 ? '请允许浏览器获取当前位置' : '当前位置获取失败')
}, { enableHighAccuracy: true, timeout: 10000 })
},
async onMapClick(event) {
const lng = event.lnglat.getLng()
const lat = event.lnglat.getLat()
this.setDraft(lng, lat, '已选择地图位置')
this.setMarker(lng, lat, true)
try {
const address = await reverseGeocode(lng, lat)
if (address) this.setDraft(lng, lat, address)
} catch (error) {
this.setDraft(lng, lat, '')
this.$message.warning('点位地址解析失败,请重新选择')
}
},
setDraft(lng, lat, address) {
this.draft = { lng, lat, address: address || '' }
},
setMarker(lng, lat, pan) {
if (!this.map || !window.T) return
if (this.marker) this.map.removeOverLay(this.marker)
this.marker = new window.T.Marker(new window.T.LngLat(lng, lat))
this.map.addOverLay(this.marker)
if (pan) this.map.panTo(new window.T.LngLat(lng, lat))
},
confirm() {
const gcj = wgs84ToGcj02(this.draft.lng, this.draft.lat)
this.$emit('input', [gcj[0], gcj[1], this.draft.address])
this.$emit('change', { longitude: gcj[0], latitude: gcj[1], address: this.draft.address })
this.dialogVisible = false
}
}
}
</script>
<style scoped>
.tdt-picker-trigger { width: 100%; }
.tdt-picker-toolbar { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.tdt-picker-search-wrap { position: relative; flex: 1; min-width: 0; }
.tdt-picker-search { width: 100%; }
.tdt-picker-current { max-width: 32%; overflow: hidden; color: #606266; white-space: nowrap; text-overflow: ellipsis; }
.tdt-picker-results { position: absolute; top: 42px; right: 0; left: 0; z-index: 3000; max-height: 260px; overflow-y: auto; background: #fff; border: 1px solid #dcdfe6; border-radius: 0 0 4px 4px; box-shadow: 0 2px 12px rgba(0, 0, 0, .12); }
.tdt-picker-result { padding: 8px 12px; cursor: pointer; border-bottom: 1px solid #f2f6fc; }
.tdt-picker-result:hover { background: #f5f7fa; }
.tdt-picker-result-name { color: #303133; font-size: 14px; }
.tdt-picker-result-address { margin-top: 3px; color: #909399; font-size: 12px; }
.tdt-picker-map { width: 100%; height: 520px; }
@media (max-width: 900px) {
.tdt-picker-toolbar { flex-wrap: wrap; }
.tdt-picker-search-wrap { flex-basis: 100%; }
.tdt-picker-current { max-width: 100%; }
.tdt-picker-map { height: 420px; }
}
</style>

@ -1,13 +1,17 @@
<template>
<div>
<avue-map v-model="map" placeholder="请选择地图"></avue-map>
</div>
<tian-di-tu-picker v-if="raw" :value="rawValue" :zoom="zoom" @input="onRawInput" />
<tian-di-tu-picker v-else :value="rawValue" :zoom="zoom" @input="onPickerInput" />
</template>
<script>
import TianDiTuPicker from '@/components/TianDiTuPicker'
export default {
components: { TianDiTuPicker },
props: {
value: [String, Object, Array, Number, Boolean],
raw: { type: Boolean, default: false },
zoom: { type: Number, default: 11 },
resultFormat: {
type: [String, Object, Array],
default: () => ['latitude', 'longitude'] //latitudelongitude,formattedAddress
@ -15,48 +19,38 @@ export default {
},
data() {
return {
map: {},
rawValue: [],
}
},
methods: {},
computed: {},
watch: {
map(newVal) {
if(!newVal) return
let res = ''
if(typeof this.resultFormat === 'string') {
res = newVal[this.resultFormat]
}
if(this.resultFormat instanceof Array) {
res = this.resultFormat.map(i => newVal[i])?.toString()
}
if(typeof this.resultFormat === 'object' && (!this.resultFormat instanceof Array)) {
let obj = {}
for(let key in this.resultFormat) {
obj[key] = newVal[this.resultFormat[key]]
}
res = obj;
created() {
this.syncValue(this.value)
},
methods: {
syncValue(value) {
if (Array.isArray(value)) this.rawValue = value
else if (typeof value === 'string' && value) this.rawValue = value.split(',')
else this.rawValue = []
},
onRawInput(value) {
this.rawValue = value
this.$emit('input', value)
},
onPickerInput(value) {
this.rawValue = value
let res = value
if (typeof this.resultFormat === 'string') res = value[this.resultFormat]
if (this.resultFormat instanceof Array) res = this.resultFormat.map(i => value[i]).toString()
if (typeof this.resultFormat === 'object' && !(this.resultFormat instanceof Array)) {
res = {}
for (const key in this.resultFormat) res[key] = value[this.resultFormat[key]]
}
this.$emit('input', res)
},
}
},
computed: {},
watch: {
value(newVal) {
if(typeof this.resultFormat === 'string') {
this.map[this.resultFormat] = Number(newVal)
}
if(this.resultFormat instanceof Array && newVal) {
let valArr = newVal.split(',')
this.resultFormat.forEach((i,index) => {
this.map[i] = Number(valArr[index])
})
}
if(typeof this.resultFormat === 'object' && (!this.resultFormat instanceof Array)) {
for(let key in this.resultFormat) {
this.map[key] = Number(newVal[key])
}
}
console.log(this.map)
this.syncValue(newVal)
}
}
}

@ -48,9 +48,6 @@ Vue.config.productionTip = false
import avue from '@smallwei/avue';
import '@smallwei/avue/lib/index.css';
Vue.use(avue)
import AvueMap from 'avue-plugin-map'
Vue.use(AvueMap);
import Print from 'vue-print-nb-jeecg'
Vue.use(Print);
@ -81,6 +78,8 @@ import tinymce from '@/components/XyTinymce'
Vue.component('my-tinymce', tinymce)
import myMap from "@/components/XyMap"
Vue.component('my-map', myMap)
// 课程表等页面使用的是 xy-map 标签,保留 my-map 兼容旧页面。
Vue.component('xy-map', myMap)
import afTableColumn from 'af-table-column'
Vue.component('af-table-column', afTableColumn)

@ -0,0 +1,105 @@
export const TIAN_DI_TU_KEY = process.env.VUE_APP_TIANDITU_KEY || 'c0e64d52ae7934dfd448c59953559c40'
let loadPromise
export function loadTianDiTu() {
if (window.T) return Promise.resolve(window.T)
if (loadPromise) return loadPromise
loadPromise = new Promise((resolve, reject) => {
const existing = document.querySelector('script[data-tianditu-sdk]')
if (existing) {
existing.addEventListener('load', () => resolve(window.T))
existing.addEventListener('error', reject)
return
}
const script = document.createElement('script')
script.dataset.tiandituSdk = 'true'
script.src = `https://api.tianditu.gov.cn/api?v=4.0&tk=${encodeURIComponent(TIAN_DI_TU_KEY)}`
script.onload = () => window.T ? resolve(window.T) : reject(new Error('天地图 SDK 加载失败'))
script.onerror = () => reject(new Error('天地图 SDK 加载失败'))
document.head.appendChild(script)
})
return loadPromise
}
const PI = Math.PI
const AXIS = 6378245.0
const EE = 0.00669342162296594323
function outOfChina(lng, lat) {
return lng < 72.004 || lng > 137.8347 || lat < 0.8293 || lat > 55.8271
}
function transformLat(x, y) {
let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x))
ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0
ret += (20.0 * Math.sin(y * PI) + 40.0 * Math.sin(y / 3.0 * PI)) * 2.0 / 3.0
ret += (160.0 * Math.sin(y / 12.0 * PI) + 320 * Math.sin(y * PI / 30.0)) * 2.0 / 3.0
return ret
}
function transformLng(x, y) {
let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x))
ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0
ret += (20.0 * Math.sin(x * PI) + 40.0 * Math.sin(x / 3.0 * PI)) * 2.0 / 3.0
ret += (150.0 * Math.sin(x / 12.0 * PI) + 300.0 * Math.sin(x / 30.0 * PI)) * 2.0 / 3.0
return ret
}
export function wgs84ToGcj02(lng, lat) {
lng = Number(lng); lat = Number(lat)
if (outOfChina(lng, lat)) return [lng, lat]
const dLat = transformLat(lng - 105.0, lat - 35.0)
const dLng = transformLng(lng - 105.0, lat - 35.0)
const radLat = lat / 180.0 * PI
let magic = Math.sin(radLat)
magic = 1 - EE * magic * magic
const sqrtMagic = Math.sqrt(magic)
return [lng + (dLng * 180.0) / (AXIS / sqrtMagic * Math.cos(radLat) * PI), lat + (dLat * 180.0) / ((AXIS * (1 - EE)) / (magic * sqrtMagic) * PI)]
}
export function gcj02ToWgs84(lng, lat) {
lng = Number(lng); lat = Number(lat)
if (outOfChina(lng, lat)) return [lng, lat]
const gcj = wgs84ToGcj02(lng, lat)
return [lng * 2 - gcj[0], lat * 2 - gcj[1]]
}
export function formatCoordinate(value) {
return Number(value).toFixed(6)
}
export async function reverseGeocode(lng, lat) {
const postStr = encodeURIComponent(JSON.stringify({ lon: Number(lng), lat: Number(lat), ver: 1 }))
const response = await fetch(`https://api.tianditu.gov.cn/geocoder?postStr=${postStr}&type=geocode&tk=${encodeURIComponent(TIAN_DI_TU_KEY)}`)
if (!response.ok) throw new Error('天地图地址解析请求失败')
const data = await response.json()
const result = data && data.result ? data.result : {}
const component = result.addressComponent || result.address_component || {}
return result.address || result.formatted_address || component.address || [
component.province,
component.city,
component.county,
component.road,
component.roadname,
component.poi
].filter(Boolean).join('')
}
export async function searchTianDiTu(keyword) {
const postStr = encodeURIComponent(JSON.stringify({
keyWord: keyword,
level: 12,
mapBound: '72,0,137,56',
queryType: 1,
count: 10,
start: 0,
show: 2
}))
const response = await fetch(`https://api.tianditu.gov.cn/v2/search?postStr=${postStr}&type=query&tk=${encodeURIComponent(TIAN_DI_TU_KEY)}`)
if (!response.ok) throw new Error('天地图搜索请求失败')
const data = await response.json()
if (data && data.code && data.code !== 1000) throw new Error(data.msg || '天地图搜索失败')
return data && Array.isArray(data.pois) ? data.pois : []
}

@ -1,18 +1,16 @@
<template>
<div>
123
<avue-input-map :params="mapparams" placeholder="请选择地图" v-model="mapform"></avue-input-map>
<xy-map raw v-model="mapform" :zoom="mapparams.zoom"></xy-map>
<xyTinymce v-model="content"></xyTinymce>
</div>
</template>
<script>
import AvueMap from 'avue-plugin-map'
import xyTinymce from "@/components/XyTinymce/index.vue";
export default{
components: {
AvueMap,
xyTinymce
},
data(){

@ -323,12 +323,7 @@
></el-input>
</el-form-item>
<el-form-item label="签到地点:">
<avue-input-map
v-model="batchMapForm"
:params="mapparams"
style="width: 100%"
placeholder="请选择地图"
/>
<xy-map raw v-model="batchMapForm" :zoom="mapparams.zoom" />
</el-form-item>
</el-form>
</div>

@ -165,7 +165,7 @@
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>签到地点
</div>
<div class="xy-table-item-content">
<avue-input-map v-model="addrMapForm" :params="mapparams" style="width:100%" placeholder="请选择地图" />
<xy-map raw v-model="addrMapForm" :zoom="mapparams.zoom" />
</div>
</div>
</template>

@ -100,7 +100,7 @@
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>签到地点
</div>
<div class="xy-table-item-content">
<avue-input-map v-model="mapform" :params="mapparams" style="width:100%" placeholder="请选择地图" />
<xy-map raw v-model="mapform" :zoom="mapparams.zoom" />
</div>
</div>
</template>

@ -260,6 +260,7 @@ import { home2 } from '@/api/home/index'
import countryData from './country.json'
import { getparameteritem } from '@/api/system/dictionary'
import { index as configIndex } from '@/api/info/configs.js'
import { loadTianDiTu } from '@/utils/tianditu'
export default {
name: 'DataScreen',
data() {
@ -304,6 +305,7 @@ export default {
mapChartInstance: null,
hoveredArea: null,
nationalMapInstance: null,
nationalMapInitTimer: null,
nationalMarkers: [],
mapData: [
{ name: '张家港市', value: 0, imageKey: 'zjg' },
@ -485,17 +487,21 @@ export default {
mapType(newVal) {
if (newVal === 'national') {
this.$nextTick(() => {
this.initNationalMap()
this.scheduleNationalMapInit()
//
this.nationalRankingPageIndex = 0
this.startNationalRankingRotation()
})
} else {
//
if (this.nationalRankingTimer) {
clearInterval(this.nationalRankingTimer)
this.nationalRankingTimer = null
}
if (this.nationalRankingTimer) {
clearInterval(this.nationalRankingTimer)
this.nationalRankingTimer = null
}
if (this.nationalMapInitTimer) {
clearTimeout(this.nationalMapInitTimer)
this.nationalMapInitTimer = null
}
}
},
nationalMapData: {
@ -542,7 +548,7 @@ export default {
this.handleResize()
window.addEventListener('resize', this.handleResize)
if (this.mapType === 'national') {
this.initNationalMap()
this.scheduleNationalMapInit()
}
},
@ -567,7 +573,7 @@ export default {
clearInterval(this.nationalRankingTimer)
}
if (this.nationalMarkers.length && this.nationalMapInstance) {
this.nationalMapInstance.remove(this.nationalMarkers)
this.nationalMarkers.forEach(marker => this.nationalMapInstance.removeOverLay(marker))
this.nationalMarkers = []
}
if (this.nationalMapInstance) {
@ -866,46 +872,95 @@ export default {
//
handleResize() {
// ,
if (this.nationalMapInstance) {
this.nationalMapInstance.resize()
}
if (this.nationalMapInstance && this.nationalMapInstance.checkResize) this.nationalMapInstance.checkResize()
},
//
scheduleNationalMapInit() {
if (this.nationalMapInitTimer) clearTimeout(this.nationalMapInitTimer)
this.nationalMapInitTimer = setTimeout(() => {
this.nationalMapInitTimer = null
this.initNationalMap()
}, 100)
},
//
initNationalMap() {
async initNationalMap() {
if (this.mapType !== 'national') return
if (this.nationalMapInstance || !this.$refs.nationalMap) {
this.renderNationalCities()
return
}
if (!(window && window.AMap)) return
this.nationalMapInstance = new window.AMap.Map(this.$refs.nationalMap, {
resizeEnable: true,
zoom: 9,
center: [120.585315, 31.298886],
mapStyle: 'amap://styles/bfb1bb3feb0db7082367abca96b8d214'
})
this.renderNationalCities()
if (!this.$refs.nationalMap.clientWidth || !this.$refs.nationalMap.clientHeight) {
this.scheduleNationalMapInit()
return
}
try {
const T = await loadTianDiTu()
if (this.mapType !== 'national' || !this.$refs.nationalMap) return
this.nationalMapInstance = new T.Map(this.$refs.nationalMap)
this.nationalMapInstance.centerAndZoom(new T.LngLat(120.585315, 31.298886), 5)
this.$nextTick(() => {
if (this.nationalMapInstance && this.nationalMapInstance.checkResize) this.nationalMapInstance.checkResize()
})
this.renderNationalCities()
} catch (error) {
this.$message.error(error.message || '天地图加载失败')
}
},
//
renderNationalCities() {
if (!this.nationalMapInstance || !(window && window.AMap)) return
if (!this.nationalMapInstance || !window.T) return
if (this.nationalMarkers.length) {
this.nationalMapInstance.remove(this.nationalMarkers)
this.nationalMarkers.forEach(marker => this.nationalMapInstance.removeOverLay(marker))
this.nationalMarkers = []
}
// 使 bottom-center
const CityMarker = window.T.Overlay.extend({
initialize(point, city) {
this.point = point
this.element = document.createElement('div')
this.element.className = 'national-marker national-city-overlay'
const bubble = document.createElement('div')
bubble.className = 'marker-text'
const name = document.createElement('span')
name.className = 'marker-name'
name.textContent = city.name + ':' + city.value + '人'
bubble.appendChild(name)
const line = document.createElement('div')
line.className = 'marker-line'
this.element.appendChild(bubble)
this.element.appendChild(line)
},
onAdd(map) {
this.map = map
map.getPanes().overlayPane.appendChild(this.element)
this.update()
},
update() {
if (!this.map) return
const pixel = this.map.lngLatToLayerPoint(this.point)
this.element.style.left = pixel.x + 'px'
this.element.style.top = (pixel.y - 20) + 'px'
},
onRemove() {
if (this.element.parentNode) this.element.parentNode.removeChild(this.element)
this.map = null
},
getElement() {
return this.element
}
})
this.nationalMapData.forEach(city => {
if (!city.lnglat || city.lnglat.length !== 2) return
const marker = new window.AMap.Marker({
position: city.lnglat,
anchor: 'bottom-center',
content: this.createMarkerContent(city),
offset: new window.AMap.Pixel(0, -20),
bubble: true
})
this.nationalMapInstance.add(marker)
this.nationalMarkers.push(marker)
try {
const point = new window.T.LngLat(city.lnglat[0], city.lnglat[1])
const marker = new CityMarker(point, city)
this.nationalMapInstance.addOverLay(marker)
this.nationalMarkers.push(marker)
} catch (error) {
console.warn('全国地图点位绘制失败:', city.name, error)
}
})
},
@ -1669,7 +1724,7 @@ export default {
font-size: 1.1vw;
position: absolute;
left: -1vw;
z-index: 1;
z-index: 10;
}
.map-tabs {
@ -1727,6 +1782,8 @@ export default {
.national-map-wrapper {
width: 100%;
height: 100%;
position: relative;
z-index: 0;
}
.national-map {
@ -1736,11 +1793,6 @@ export default {
overflow: hidden;
}
.national-map-wrapper ::v-deep .amap-logo,
.national-map-wrapper ::v-deep .amap-copyright {
display: none !important;
}
::v-deep .national-marker {
display: flex;
flex-direction: column;
@ -1748,6 +1800,12 @@ export default {
gap: 0.3vh;
}
::v-deep .national-city-overlay {
position: absolute;
transform: translate(-50%, -100%);
pointer-events: none;
}
::v-deep .national-marker .marker-text {
padding: 0.6vh 0.5vw;
background: #fff;

Loading…
Cancel
Save