| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- <template>
- <div class="hazard-map-container">
- <el-card class="legend-card">
- <template #header><span>图例说明</span></template>
- <div class="legend-items">
- <div class="legend-item" v-for="item in levelLegend" :key="item.value">
- <span class="dot" :style="{ background: item.color }"></span> {{ item.label }}隐患
- </div>
- </div>
- </el-card>
- <div id="hazardMap" class="map-container"></div>
- <el-drawer v-model="detailVisible" title="隐患详情" size="400px">
- <template v-if="currentHazard">
- <el-descriptions :column="1" border size="small">
- <el-descriptions-item label="隐患编号">{{ currentHazard.hazardNo }}</el-descriptions-item>
- <el-descriptions-item label="隐患类型">{{ getDictLabel(hazardTypeDict, currentHazard.hazardType) }}</el-descriptions-item>
- <el-descriptions-item label="隐患等级">
- <el-tag :type="levelTag(currentHazard.hazardLevel)">{{ getDictLabel(hazardLevelDict, currentHazard.hazardLevel) }}</el-tag>
- </el-descriptions-item>
- <el-descriptions-item label="状态">{{ getDictLabel(hazardStatusDict, currentHazard.hazardStatus) }}</el-descriptions-item>
- <el-descriptions-item label="隐患描述">{{ currentHazard.hazardDesc }}</el-descriptions-item>
- <el-descriptions-item label="整改反馈">{{ currentHazard.rectifyFeedback || '暂无' }}</el-descriptions-item>
- <el-descriptions-item label="上报时间">{{ currentHazard.reportTime }}</el-descriptions-item>
- </el-descriptions>
- </template>
- </el-drawer>
- </div>
- </template>
- <script setup>
- import { ref, computed, onMounted, nextTick } from 'vue'
- import { getHazardMapPoints } from '@/api/pipeNetwork/hazard'
- import { getDicts } from '@/api/system/dict/data'
- const detailVisible = ref(false)
- const currentHazard = ref(null)
- let mapInstance = null
- const hazardTypeDict = ref([])
- const hazardLevelDict = ref([])
- const hazardStatusDict = ref([])
- function getDictLabel(dict, value) {
- const item = dict.find(d => d.dictValue === value)
- return item ? item.dictLabel : value
- }
- const levelColors = { '0': '#f5222d', '1': '#fa8c16', '2': '#1890ff', '3': '#52c41a' }
- function levelTag(level) {
- const map = { '0': 'danger', '1': 'warning', '2': '', '3': 'success' }
- return map[level] || ''
- }
- const levelLegend = computed(() =>
- hazardLevelDict.value.map(d => ({ value: d.dictValue, label: d.dictLabel, color: levelColors[d.dictValue] || '#999' }))
- )
- async function loadDicts() {
- const [typeRes, levelRes, statusRes] = await Promise.all([
- getDicts('hazard_type'),
- getDicts('hazard_level'),
- getDicts('hazard_status')
- ])
- hazardTypeDict.value = typeRes.data
- hazardLevelDict.value = levelRes.data
- hazardStatusDict.value = statusRes.data
- }
- async function initMap() {
- await nextTick()
- const el = document.getElementById('hazardMap')
- if (!el) return
- try {
- const L = await import('leaflet')
- mapInstance = L.map('hazardMap').setView([34.77, 113.65], 12)
- L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
- attribution: '© OpenStreetMap contributors'
- }).addTo(mapInstance)
- const res = await getHazardMapPoints()
- const points = res.data || []
- for (const p of points) {
- if (!p.longitude || !p.latitude) continue
- const color = levelColors[p.hazardLevel] || '#999'
- const marker = L.circleMarker([p.latitude, p.longitude], {
- radius: 10, fillColor: color, color: '#fff', weight: 2, fillOpacity: 0.8
- }).addTo(mapInstance)
- const typeLabel = getDictLabel(hazardTypeDict, p.hazardType)
- const levelLabel = getDictLabel(hazardLevelDict, p.hazardLevel)
- const statusLabel = getDictLabel(hazardStatusDict, p.hazardStatus)
- marker.bindPopup(`<b>${p.hazardNo}</b><br/>${typeLabel} | ${levelLabel}<br/>${statusLabel}`)
- marker.on('click', () => { currentHazard.value = p; detailVisible.value = true })
- }
- } catch (e) {
- el.innerHTML = '<div style="display:flex;align-items:center;justify-content:center;height:100%;color:#999;">请安装Leaflet: npm install leaflet</div>'
- }
- }
- onMounted(async () => { await loadDicts(); initMap() })
- </script>
- <style scoped>
- .hazard-map-container { position: relative; height: calc(100vh - 100px); padding: 16px; }
- .legend-card { position: absolute; top: 32px; right: 32px; z-index: 1000; width: 160px; }
- .legend-items { display: flex; flex-direction: column; gap: 6px; }
- .legend-item { display: flex; align-items: center; gap: 6px; font-size: 13px; }
- .dot { width: 12px; height: 12px; border-radius: 50%; display: inline-block; }
- .map-container { width: 100%; height: 100%; border-radius: 4px; }
- </style>
|