|
@@ -1,13 +1,31 @@
|
|
|
<template>
|
|
<template>
|
|
|
<div class="app-container">
|
|
<div class="app-container">
|
|
|
|
|
+ <!-- GIS 地图展示区 -->
|
|
|
|
|
+ <div class="map-section" style="margin-bottom: 16px;">
|
|
|
|
|
+ <div class="map-tabs">
|
|
|
|
|
+ <div class="map-tab" :class="{ active: mainMapTab === 'all' }" @click="switchMainMapTab('all')">全部</div>
|
|
|
|
|
+ <div class="map-tab" :class="{ active: mainMapTab === 'gate' }" @click="switchMainMapTab('gate')">闸门</div>
|
|
|
|
|
+ <div class="map-tab" :class="{ active: mainMapTab === 'storage' }" @click="switchMainMapTab('storage')">调蓄设施</div>
|
|
|
|
|
+ <div class="map-tab" :class="{ active: mainMapTab === 'pump' }" @click="switchMainMapTab('pump')">泵站</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div id="gcssglMainMap" class="map-container" style="height: 350px;"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
<!-- 搜索区域 -->
|
|
<!-- 搜索区域 -->
|
|
|
<el-form :model="queryParams" ref="queryRef" :inline="true" class="search-form">
|
|
<el-form :model="queryParams" ref="queryRef" :inline="true" class="search-form">
|
|
|
- <el-form-item label="监测点名称">
|
|
|
|
|
|
|
+ <el-form-item label="设施名称">
|
|
|
<el-input v-model="queryParams.name" placeholder="请输入" clearable style="width: 200px" />
|
|
<el-input v-model="queryParams.name" placeholder="请输入" clearable style="width: 200px" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item label="行政区域">
|
|
<el-form-item label="行政区域">
|
|
|
<el-input v-model="queryParams.area" placeholder="请输入" clearable style="width: 200px" />
|
|
<el-input v-model="queryParams.area" placeholder="请输入" clearable style="width: 200px" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
+ <el-form-item label="设施类型">
|
|
|
|
|
+ <el-select v-model="queryParams.facilityType" placeholder="请选择" clearable style="width: 200px">
|
|
|
|
|
+ <el-option label="闸门" value="闸门" />
|
|
|
|
|
+ <el-option label="调蓄设施" value="调蓄设施" />
|
|
|
|
|
+ <el-option label="泵站" value="泵站" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
<el-form-item>
|
|
<el-form-item>
|
|
|
<el-button type="primary" @click="handleQuery">搜索</el-button>
|
|
<el-button type="primary" @click="handleQuery">搜索</el-button>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
@@ -20,14 +38,13 @@
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<!-- 数据表格 -->
|
|
<!-- 数据表格 -->
|
|
|
- <el-table :data="filteredList" border style="width: 100%" @selection-change="handleSelectionChange">
|
|
|
|
|
|
|
+ <el-table v-loading="loading" :data="filteredList" border style="width: 100%" @selection-change="handleSelectionChange">
|
|
|
<el-table-column type="selection" width="55" align="center" />
|
|
<el-table-column type="selection" width="55" align="center" />
|
|
|
<el-table-column label="监测点名称" prop="name" min-width="160" />
|
|
<el-table-column label="监测点名称" prop="name" min-width="160" />
|
|
|
<el-table-column label="行政区域" prop="area" min-width="100" />
|
|
<el-table-column label="行政区域" prop="area" min-width="100" />
|
|
|
|
|
+ <el-table-column label="设施类型" prop="facilityType" min-width="100" />
|
|
|
<el-table-column label="数据时间" prop="time" min-width="120" />
|
|
<el-table-column label="数据时间" prop="time" min-width="120" />
|
|
|
- <el-table-column label="闸门数量" prop="gateCount" min-width="80" />
|
|
|
|
|
- <el-table-column label="调蓄数量" prop="storageCount" min-width="80" />
|
|
|
|
|
- <el-table-column label="泵站数量" prop="pumpCount" min-width="80" />
|
|
|
|
|
|
|
+ <el-table-column label="标记数量" prop="pointCount" min-width="80" />
|
|
|
<el-table-column label="操作" width="180" align="center">
|
|
<el-table-column label="操作" width="180" align="center">
|
|
|
<template #default="{ row }">
|
|
<template #default="{ row }">
|
|
|
<el-button link type="primary" @click="handleView(row)">查看</el-button>
|
|
<el-button link type="primary" @click="handleView(row)">查看</el-button>
|
|
@@ -37,6 +54,18 @@
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
</el-table>
|
|
</el-table>
|
|
|
|
|
|
|
|
|
|
+ <!-- 分页 -->
|
|
|
|
|
+ <el-pagination
|
|
|
|
|
+ v-model:current-page="pageNum"
|
|
|
|
|
+ v-model:page-size="pageSize"
|
|
|
|
|
+ :total="total"
|
|
|
|
|
+ :page-sizes="[10, 20, 50, 100]"
|
|
|
|
|
+ layout="total, sizes, prev, pager, next, jumper"
|
|
|
|
|
+ style="margin-top: 16px; justify-content: flex-end;"
|
|
|
|
|
+ @size-change="loadData"
|
|
|
|
|
+ @current-change="loadData"
|
|
|
|
|
+ />
|
|
|
|
|
+
|
|
|
<!-- 查看详情对话框 -->
|
|
<!-- 查看详情对话框 -->
|
|
|
<el-dialog v-model="dialogVisible" title="详情" width="700px" :before-close="handleClose" @opened="onDialogOpened">
|
|
<el-dialog v-model="dialogVisible" title="详情" width="700px" :before-close="handleClose" @opened="onDialogOpened">
|
|
|
<div class="detail-info">
|
|
<div class="detail-info">
|
|
@@ -57,28 +86,22 @@
|
|
|
<el-row :gutter="20">
|
|
<el-row :gutter="20">
|
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
|
<div class="info-item">
|
|
<div class="info-item">
|
|
|
- <span class="info-label">数据时间:</span>
|
|
|
|
|
- <span class="info-value">{{ currentRow.time }}</span>
|
|
|
|
|
|
|
+ <span class="info-label">设施类型:</span>
|
|
|
|
|
+ <span class="info-value">{{ currentRow.facilityType }}</span>
|
|
|
</div>
|
|
</div>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
|
<div class="info-item">
|
|
<div class="info-item">
|
|
|
- <span class="info-label">闸门数量:</span>
|
|
|
|
|
- <span class="info-value">{{ (currentRow.gatePoints || []).length }}</span>
|
|
|
|
|
|
|
+ <span class="info-label">数据时间:</span>
|
|
|
|
|
+ <span class="info-value">{{ currentRow.time }}</span>
|
|
|
</div>
|
|
</div>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
|
<el-row :gutter="20">
|
|
<el-row :gutter="20">
|
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
|
<div class="info-item">
|
|
<div class="info-item">
|
|
|
- <span class="info-label">调蓄数量:</span>
|
|
|
|
|
- <span class="info-value">{{ (currentRow.storagePoints || []).length }}</span>
|
|
|
|
|
- </div>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- <el-col :span="12">
|
|
|
|
|
- <div class="info-item">
|
|
|
|
|
- <span class="info-label">泵站数量:</span>
|
|
|
|
|
- <span class="info-value">{{ (currentRow.pumpPoints || []).length }}</span>
|
|
|
|
|
|
|
+ <span class="info-label">标记数量:</span>
|
|
|
|
|
+ <span class="info-value">{{ currentRowPointCount }}</span>
|
|
|
</div>
|
|
</div>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
@@ -87,12 +110,7 @@
|
|
|
<!-- 地图区域 -->
|
|
<!-- 地图区域 -->
|
|
|
<div class="map-section">
|
|
<div class="map-section">
|
|
|
<div class="map-tabs">
|
|
<div class="map-tabs">
|
|
|
- <div class="map-tab" :class="{ active: viewMapTab === 'gate' }"
|
|
|
|
|
- @click="switchViewMapTab('gate')">闸门</div>
|
|
|
|
|
- <div class="map-tab" :class="{ active: viewMapTab === 'storage' }"
|
|
|
|
|
- @click="switchViewMapTab('storage')">调蓄设施</div>
|
|
|
|
|
- <div class="map-tab" :class="{ active: viewMapTab === 'pump' }"
|
|
|
|
|
- @click="switchViewMapTab('pump')">泵站</div>
|
|
|
|
|
|
|
+ <div class="map-tab active">{{ currentRow.facilityType || '位置标记' }}</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div id="gcssglViewMap" class="map-container"></div>
|
|
<div id="gcssglViewMap" class="map-container"></div>
|
|
|
</div>
|
|
</div>
|
|
@@ -115,6 +133,16 @@
|
|
|
</el-col>
|
|
</el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
|
<el-row :gutter="20">
|
|
<el-row :gutter="20">
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="设施类型" prop="facilityType">
|
|
|
|
|
+ <el-select v-model="editForm.facilityType" placeholder="请选择设施类型" style="width:100%"
|
|
|
|
|
+ @change="onFacilityTypeChange">
|
|
|
|
|
+ <el-option label="闸门" value="闸门" />
|
|
|
|
|
+ <el-option label="调蓄设施" value="调蓄设施" />
|
|
|
|
|
+ <el-option label="泵站" value="泵站" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
|
<el-form-item label="数据时间" prop="time">
|
|
<el-form-item label="数据时间" prop="time">
|
|
|
<el-date-picker v-model="editForm.time" type="date" placeholder="请选择日期" value-format="YYYY-MM-DD"
|
|
<el-date-picker v-model="editForm.time" type="date" placeholder="请选择日期" value-format="YYYY-MM-DD"
|
|
@@ -123,19 +151,9 @@
|
|
|
</el-col>
|
|
</el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
|
<el-row :gutter="20">
|
|
<el-row :gutter="20">
|
|
|
- <el-col :span="8">
|
|
|
|
|
- <el-form-item label="闸门数量">
|
|
|
|
|
- <el-input :model-value="editGatePoints.length" disabled />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- <el-col :span="8">
|
|
|
|
|
- <el-form-item label="调蓄数量">
|
|
|
|
|
- <el-input :model-value="editStoragePoints.length" disabled />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- <el-col :span="8">
|
|
|
|
|
- <el-form-item label="泵站数量">
|
|
|
|
|
- <el-input :model-value="editPumpPoints.length" disabled />
|
|
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="标记数量">
|
|
|
|
|
+ <el-input :model-value="editPoints.length" disabled />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
@@ -144,17 +162,12 @@
|
|
|
<!-- 地图标点区域 -->
|
|
<!-- 地图标点区域 -->
|
|
|
<div class="map-section" style="margin-top: 16px;">
|
|
<div class="map-section" style="margin-top: 16px;">
|
|
|
<div class="map-tabs">
|
|
<div class="map-tabs">
|
|
|
- <div class="map-tab" :class="{ active: editMapTab === 'gate' }"
|
|
|
|
|
- @click="switchEditMapTab('gate')">闸门</div>
|
|
|
|
|
- <div class="map-tab" :class="{ active: editMapTab === 'storage' }"
|
|
|
|
|
- @click="switchEditMapTab('storage')">调蓄设施</div>
|
|
|
|
|
- <div class="map-tab" :class="{ active: editMapTab === 'pump' }"
|
|
|
|
|
- @click="switchEditMapTab('pump')">泵站</div>
|
|
|
|
|
|
|
+ <div class="map-tab active">{{ editForm.facilityType || '位置标记' }}</div>
|
|
|
<div class="map-tab-action" @click="clearEditMarkers">清除所有标记</div>
|
|
<div class="map-tab-action" @click="clearEditMarkers">清除所有标记</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div id="gcssglEditMap" class="map-container" style="height: 350px;"></div>
|
|
<div id="gcssglEditMap" class="map-container" style="height: 350px;"></div>
|
|
|
<div class="marker-count">
|
|
<div class="marker-count">
|
|
|
- 已标记 {{ currentEditPoints.length }} 个{{ editMapTabLabel }}
|
|
|
|
|
|
|
+ 已标记 {{ editPoints.length }} 个{{ editForm.facilityType || '标记' }}
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -167,14 +180,21 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup name="Gcssgl">
|
|
<script setup name="Gcssgl">
|
|
|
-import { ref, computed } from 'vue'
|
|
|
|
|
|
|
+import { ref, computed, onMounted } from 'vue'
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
import locationIcon from '@/assets/images/location.png'
|
|
import locationIcon from '@/assets/images/location.png'
|
|
|
|
|
+import {
|
|
|
|
|
+ getFacilityPage,
|
|
|
|
|
+ addFacility,
|
|
|
|
|
+ updateFacility,
|
|
|
|
|
+ deleteFacility
|
|
|
|
|
+} from '@/api/drainage'
|
|
|
|
|
|
|
|
// 地图标记创建(用Label+img代替Marker)
|
|
// 地图标记创建(用Label+img代替Marker)
|
|
|
-function createMapMarker(map, bPoint, name) {
|
|
|
|
|
|
|
+function createMapMarker(map, bPoint, name, bgColor) {
|
|
|
|
|
+ const color = bgColor || '#409eff'
|
|
|
const html = `<div style="text-align:center;cursor:pointer;">
|
|
const html = `<div style="text-align:center;cursor:pointer;">
|
|
|
- <div style="color:#fff;background:#409eff;border-radius:4px;padding:2px 6px;font-size:11px;white-space:nowrap;display:inline-block;margin-bottom:2px;">${name || ''}</div>
|
|
|
|
|
|
|
+ <div style="color:#fff;background:${color};border-radius:4px;padding:2px 6px;font-size:11px;white-space:nowrap;display:inline-block;margin-bottom:2px;">${name || ''}</div>
|
|
|
<div><img src="${locationIcon}" style="width:28px;height:28px;display:block;margin:0 auto;"/></div>
|
|
<div><img src="${locationIcon}" style="width:28px;height:28px;display:block;margin:0 auto;"/></div>
|
|
|
</div>`
|
|
</div>`
|
|
|
const label = new BMapGL.Label(html, {
|
|
const label = new BMapGL.Label(html, {
|
|
@@ -190,77 +210,106 @@ function createMapMarker(map, bPoint, name) {
|
|
|
return label
|
|
return label
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// 解析坐标数据(兼容JSON字符串和数组)
|
|
|
|
|
+function parsePoints(data) {
|
|
|
|
|
+ if (!data) return []
|
|
|
|
|
+ if (typeof data === 'string') {
|
|
|
|
|
+ try { return JSON.parse(data) } catch (e) { return [] }
|
|
|
|
|
+ }
|
|
|
|
|
+ return Array.isArray(data) ? data : []
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// ==================== 顶部主地图 ====================
|
|
|
|
|
+let mainMapInstance = null
|
|
|
|
|
+const mainMapTab = ref('all')
|
|
|
|
|
+
|
|
|
|
|
+function switchMainMapTab(tab) {
|
|
|
|
|
+ mainMapTab.value = tab
|
|
|
|
|
+ renderMainMapMarkers()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function initMainMap() {
|
|
|
|
|
+ const container = document.getElementById('gcssglMainMap')
|
|
|
|
|
+ if (!container) return
|
|
|
|
|
+ try {
|
|
|
|
|
+ mainMapInstance = new BMapGL.Map('gcssglMainMap')
|
|
|
|
|
+ const centerPoint = new BMapGL.Point(110.393, 28.452)
|
|
|
|
|
+ mainMapInstance.centerAndZoom(centerPoint, 12)
|
|
|
|
|
+ mainMapInstance.enableScrollWheelZoom(true)
|
|
|
|
|
+ renderMainMapMarkers()
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ console.error('顶部百度地图初始化失败:', e)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function renderMainMapMarkers() {
|
|
|
|
|
+ if (!mainMapInstance) return
|
|
|
|
|
+ mainMapInstance.clearOverlays()
|
|
|
|
|
+
|
|
|
|
|
+ const allPoints = []
|
|
|
|
|
+ const tab = mainMapTab.value
|
|
|
|
|
+ const typeMap = { gate: '闸门', storage: '调蓄设施', pump: '泵站' }
|
|
|
|
|
+ const colorMap = { '闸门': '#409eff', '调蓄设施': '#e6a23c', '泵站': '#67c23a' }
|
|
|
|
|
+ const targetType = tab === 'all' ? null : typeMap[tab]
|
|
|
|
|
+
|
|
|
|
|
+ tableData.value.forEach(row => {
|
|
|
|
|
+ if (targetType && row.facilityType !== targetType) return
|
|
|
|
|
+ const points = parsePoints(row.points)
|
|
|
|
|
+ const color = colorMap[row.facilityType] || '#409eff'
|
|
|
|
|
+
|
|
|
|
|
+ points.forEach(p => {
|
|
|
|
|
+ if (p.lng && p.lat) {
|
|
|
|
|
+ const bPoint = new BMapGL.Point(p.lng, p.lat)
|
|
|
|
|
+ createMapMarker(mainMapInstance, bPoint, p.name || row.name, color)
|
|
|
|
|
+ allPoints.push(bPoint)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ if (allPoints.length > 0) {
|
|
|
|
|
+ mainMapInstance.setViewport(allPoints)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// ==================== 搜索参数 ====================
|
|
// ==================== 搜索参数 ====================
|
|
|
const queryParams = ref({
|
|
const queryParams = ref({
|
|
|
name: '',
|
|
name: '',
|
|
|
- area: ''
|
|
|
|
|
|
|
+ area: '',
|
|
|
|
|
+ facilityType: ''
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
// ==================== 表格数据 ====================
|
|
// ==================== 表格数据 ====================
|
|
|
-let nextId = 5
|
|
|
|
|
-const tableData = ref([
|
|
|
|
|
- {
|
|
|
|
|
- id: 1, name: '沅陵北路1号工程设施', area: '沅陵县', time: '2025-12-31',
|
|
|
|
|
- gateCount: 3, storageCount: 2, pumpCount: 2,
|
|
|
|
|
- gatePoints: [
|
|
|
|
|
- { name: '闸门1', lng: 110.393, lat: 28.452 },
|
|
|
|
|
- { name: '闸门2', lng: 110.398, lat: 28.455 },
|
|
|
|
|
- { name: '闸门3', lng: 110.402, lat: 28.450 }
|
|
|
|
|
- ],
|
|
|
|
|
- storagePoints: [
|
|
|
|
|
- { name: '调蓄设施1', lng: 110.395, lat: 28.448 },
|
|
|
|
|
- { name: '调蓄设施2', lng: 110.400, lat: 28.460 }
|
|
|
|
|
- ],
|
|
|
|
|
- pumpPoints: [
|
|
|
|
|
- { name: '泵站1', lng: 110.390, lat: 28.445 },
|
|
|
|
|
- { name: '泵站2', lng: 110.408, lat: 28.458 }
|
|
|
|
|
- ]
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- id: 2, name: '沅陵南路1号工程设施', area: '沅陵县', time: '2025-12-30',
|
|
|
|
|
- gateCount: 2, storageCount: 1, pumpCount: 1,
|
|
|
|
|
- gatePoints: [
|
|
|
|
|
- { name: '闸门1', lng: 110.385, lat: 28.446 },
|
|
|
|
|
- { name: '闸门2', lng: 110.390, lat: 28.444 }
|
|
|
|
|
- ],
|
|
|
|
|
- storagePoints: [
|
|
|
|
|
- { name: '调蓄设施1', lng: 110.388, lat: 28.450 }
|
|
|
|
|
- ],
|
|
|
|
|
- pumpPoints: [
|
|
|
|
|
- { name: '泵站1', lng: 110.392, lat: 28.442 }
|
|
|
|
|
- ]
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- id: 3, name: '沅陵东路2号工程设施', area: '沅陵县', time: '2025-12-29',
|
|
|
|
|
- gateCount: 2, storageCount: 2, pumpCount: 3,
|
|
|
|
|
- gatePoints: [
|
|
|
|
|
- { name: '闸门1', lng: 110.400, lat: 28.456 },
|
|
|
|
|
- { name: '闸门2', lng: 110.405, lat: 28.458 }
|
|
|
|
|
- ],
|
|
|
|
|
- storagePoints: [
|
|
|
|
|
- { name: '调蓄设施1', lng: 110.403, lat: 28.454 },
|
|
|
|
|
- { name: '调蓄设施2', lng: 110.409, lat: 28.461 }
|
|
|
|
|
- ],
|
|
|
|
|
- pumpPoints: [
|
|
|
|
|
- { name: '泵站1', lng: 110.413, lat: 28.461 },
|
|
|
|
|
- { name: '泵站2', lng: 110.396, lat: 28.457 },
|
|
|
|
|
- { name: '泵站3', lng: 110.410, lat: 28.453 }
|
|
|
|
|
- ]
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- id: 4, name: '沅陵西路1号工程设施', area: '沅陵县', time: '2025-12-28',
|
|
|
|
|
- gateCount: 1, storageCount: 1, pumpCount: 1,
|
|
|
|
|
- gatePoints: [
|
|
|
|
|
- { name: '闸门1', lng: 110.380, lat: 28.450 }
|
|
|
|
|
- ],
|
|
|
|
|
- storagePoints: [
|
|
|
|
|
- { name: '调蓄设施1', lng: 110.382, lat: 28.448 }
|
|
|
|
|
- ],
|
|
|
|
|
- pumpPoints: [
|
|
|
|
|
- { name: '泵站1', lng: 110.378, lat: 28.446 }
|
|
|
|
|
- ]
|
|
|
|
|
|
|
+const tableData = ref([])
|
|
|
|
|
+const total = ref(0)
|
|
|
|
|
+const pageNum = ref(1)
|
|
|
|
|
+const pageSize = ref(10)
|
|
|
|
|
+const loading = ref(false)
|
|
|
|
|
+
|
|
|
|
|
+// 加载分页数据
|
|
|
|
|
+async function loadData() {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await getFacilityPage(pageNum.value, pageSize.value, queryParams.value)
|
|
|
|
|
+ const pageData = res.code !== undefined ? res.data : res
|
|
|
|
|
+ const records = pageData.records || []
|
|
|
|
|
+ records.forEach(row => {
|
|
|
|
|
+ const pts = parsePoints(row.points)
|
|
|
|
|
+ row.pointCount = pts.length
|
|
|
|
|
+ })
|
|
|
|
|
+ tableData.value = records
|
|
|
|
|
+ total.value = pageData.total || 0
|
|
|
|
|
+ renderMainMapMarkers()
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ console.error('加载工程设施数据失败', e)
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.value = false
|
|
|
}
|
|
}
|
|
|
-])
|
|
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ loadData()
|
|
|
|
|
+ setTimeout(() => { initMainMap() }, 500)
|
|
|
|
|
+})
|
|
|
|
|
|
|
|
// 多选
|
|
// 多选
|
|
|
const selectedIds = ref([])
|
|
const selectedIds = ref([])
|
|
@@ -268,49 +317,39 @@ function handleSelectionChange(selection) {
|
|
|
selectedIds.value = selection.map(item => item.id)
|
|
selectedIds.value = selection.map(item => item.id)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 过滤后的列表
|
|
|
|
|
-const filteredList = computed(() => {
|
|
|
|
|
- return tableData.value.filter(item => {
|
|
|
|
|
- const nameMatch = !queryParams.value.name || item.name.includes(queryParams.value.name)
|
|
|
|
|
- const areaMatch = !queryParams.value.area || item.area.includes(queryParams.value.area)
|
|
|
|
|
- return nameMatch && areaMatch
|
|
|
|
|
- })
|
|
|
|
|
-})
|
|
|
|
|
|
|
+const filteredList = computed(() => tableData.value)
|
|
|
|
|
|
|
|
-// 搜索
|
|
|
|
|
function handleQuery() {
|
|
function handleQuery() {
|
|
|
- queryParams.value = { ...queryParams.value }
|
|
|
|
|
|
|
+ pageNum.value = 1
|
|
|
|
|
+ loadData()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ==================== 查看详情对话框 ====================
|
|
// ==================== 查看详情对话框 ====================
|
|
|
const dialogVisible = ref(false)
|
|
const dialogVisible = ref(false)
|
|
|
const currentRow = ref({})
|
|
const currentRow = ref({})
|
|
|
-const viewMapTab = ref('gate')
|
|
|
|
|
let viewMapInstance = null
|
|
let viewMapInstance = null
|
|
|
|
|
|
|
|
|
|
+const currentRowPointCount = computed(() => {
|
|
|
|
|
+ return parsePoints(currentRow.value.points).length
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
function handleView(row) {
|
|
function handleView(row) {
|
|
|
currentRow.value = { ...row }
|
|
currentRow.value = { ...row }
|
|
|
- viewMapTab.value = 'gate'
|
|
|
|
|
dialogVisible.value = true
|
|
dialogVisible.value = true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function handleClose() {
|
|
function handleClose() {
|
|
|
dialogVisible.value = false
|
|
dialogVisible.value = false
|
|
|
- if (viewMapInstance) {
|
|
|
|
|
- viewMapInstance = null
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (viewMapInstance) { viewMapInstance = null }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function onDialogOpened() {
|
|
function onDialogOpened() {
|
|
|
- setTimeout(() => {
|
|
|
|
|
- initViewMap()
|
|
|
|
|
- }, 300)
|
|
|
|
|
|
|
+ setTimeout(() => { initViewMap() }, 300)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function initViewMap() {
|
|
function initViewMap() {
|
|
|
const container = document.getElementById('gcssglViewMap')
|
|
const container = document.getElementById('gcssglViewMap')
|
|
|
if (!container) return
|
|
if (!container) return
|
|
|
-
|
|
|
|
|
try {
|
|
try {
|
|
|
viewMapInstance = new BMapGL.Map('gcssglViewMap')
|
|
viewMapInstance = new BMapGL.Map('gcssglViewMap')
|
|
|
const centerPoint = new BMapGL.Point(110.393, 28.452)
|
|
const centerPoint = new BMapGL.Point(110.393, 28.452)
|
|
@@ -322,22 +361,17 @@ function initViewMap() {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function getViewPoints() {
|
|
|
|
|
- const tab = viewMapTab.value
|
|
|
|
|
- if (tab === 'gate') return currentRow.value.gatePoints || []
|
|
|
|
|
- if (tab === 'storage') return currentRow.value.storagePoints || []
|
|
|
|
|
- return currentRow.value.pumpPoints || []
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
function renderViewMarkers() {
|
|
function renderViewMarkers() {
|
|
|
if (!viewMapInstance) return
|
|
if (!viewMapInstance) return
|
|
|
viewMapInstance.clearOverlays()
|
|
viewMapInstance.clearOverlays()
|
|
|
|
|
|
|
|
- const points = getViewPoints()
|
|
|
|
|
|
|
+ const points = parsePoints(currentRow.value.points)
|
|
|
|
|
+ const colorMap = { '闸门': '#409eff', '调蓄设施': '#e6a23c', '泵站': '#67c23a' }
|
|
|
|
|
+ const color = colorMap[currentRow.value.facilityType] || '#409eff'
|
|
|
|
|
|
|
|
points.forEach(point => {
|
|
points.forEach(point => {
|
|
|
const bPoint = new BMapGL.Point(point.lng, point.lat)
|
|
const bPoint = new BMapGL.Point(point.lng, point.lat)
|
|
|
- createMapMarker(viewMapInstance, bPoint, point.name)
|
|
|
|
|
|
|
+ createMapMarker(viewMapInstance, bPoint, point.name, color)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
if (points.length > 0) {
|
|
if (points.length > 0) {
|
|
@@ -346,11 +380,6 @@ function renderViewMarkers() {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function switchViewMapTab(tab) {
|
|
|
|
|
- viewMapTab.value = tab
|
|
|
|
|
- renderViewMarkers()
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
// ==================== 新增/修改对话框 ====================
|
|
// ==================== 新增/修改对话框 ====================
|
|
|
const editDialogVisible = ref(false)
|
|
const editDialogVisible = ref(false)
|
|
|
const editDialogTitle = ref('新增监测点')
|
|
const editDialogTitle = ref('新增监测点')
|
|
@@ -361,60 +390,38 @@ const editRowId = ref(null)
|
|
|
const editForm = ref({
|
|
const editForm = ref({
|
|
|
name: '',
|
|
name: '',
|
|
|
area: '',
|
|
area: '',
|
|
|
|
|
+ facilityType: '',
|
|
|
time: '',
|
|
time: '',
|
|
|
- gateCount: '',
|
|
|
|
|
- storageCount: '',
|
|
|
|
|
- pumpCount: ''
|
|
|
|
|
|
|
+ pointCount: 0,
|
|
|
|
|
+ points: []
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
const editRules = {
|
|
const editRules = {
|
|
|
name: [{ required: true, message: '请输入监测点名称', trigger: 'blur' }],
|
|
name: [{ required: true, message: '请输入监测点名称', trigger: 'blur' }],
|
|
|
area: [{ required: true, message: '请输入行政区域', trigger: 'blur' }],
|
|
area: [{ required: true, message: '请输入行政区域', trigger: 'blur' }],
|
|
|
|
|
+ facilityType: [{ required: true, message: '请选择设施类型', trigger: 'change' }],
|
|
|
time: [{ required: true, message: '请选择数据时间', trigger: 'change' }]
|
|
time: [{ required: true, message: '请选择数据时间', trigger: 'change' }]
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 编辑弹窗地图相关
|
|
// 编辑弹窗地图相关
|
|
|
-const editMapTab = ref('gate')
|
|
|
|
|
let editMapInstance = null
|
|
let editMapInstance = null
|
|
|
-let editGatePoints = ref([])
|
|
|
|
|
-let editStoragePoints = ref([])
|
|
|
|
|
-let editPumpPoints = ref([])
|
|
|
|
|
-let editGateMarkerCount = ref(0)
|
|
|
|
|
-let editStorageMarkerCount = ref(0)
|
|
|
|
|
-let editPumpMarkerCount = ref(0)
|
|
|
|
|
-
|
|
|
|
|
-// tab 中文名称
|
|
|
|
|
-const editMapTabLabel = computed(() => {
|
|
|
|
|
- const map = { gate: '闸门', storage: '调蓄设施', pump: '泵站' }
|
|
|
|
|
- return map[editMapTab.value] || ''
|
|
|
|
|
-})
|
|
|
|
|
|
|
+let editPoints = ref([])
|
|
|
|
|
+let editMarkerCount = ref(0)
|
|
|
|
|
|
|
|
-// 当前 tab 对应的点列表
|
|
|
|
|
-const currentEditPoints = computed(() => {
|
|
|
|
|
- if (editMapTab.value === 'gate') return editGatePoints.value
|
|
|
|
|
- if (editMapTab.value === 'storage') return editStoragePoints.value
|
|
|
|
|
- return editPumpPoints.value
|
|
|
|
|
-})
|
|
|
|
|
|
|
+// 设施类型变更时,清空已有标记
|
|
|
|
|
+function onFacilityTypeChange() {
|
|
|
|
|
+ editPoints.value = []
|
|
|
|
|
+ editMarkerCount.value = 0
|
|
|
|
|
+ renderEditMarkers()
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
function handleAdd() {
|
|
function handleAdd() {
|
|
|
isEditMode.value = false
|
|
isEditMode.value = false
|
|
|
editDialogTitle.value = '新增监测点'
|
|
editDialogTitle.value = '新增监测点'
|
|
|
editRowId.value = null
|
|
editRowId.value = null
|
|
|
- editForm.value = {
|
|
|
|
|
- name: '',
|
|
|
|
|
- area: '',
|
|
|
|
|
- time: '',
|
|
|
|
|
- gateCount: '',
|
|
|
|
|
- storageCount: '',
|
|
|
|
|
- pumpCount: ''
|
|
|
|
|
- }
|
|
|
|
|
- editMapTab.value = 'gate'
|
|
|
|
|
- editGatePoints.value = []
|
|
|
|
|
- editStoragePoints.value = []
|
|
|
|
|
- editPumpPoints.value = []
|
|
|
|
|
- editGateMarkerCount.value = 0
|
|
|
|
|
- editStorageMarkerCount.value = 0
|
|
|
|
|
- editPumpMarkerCount.value = 0
|
|
|
|
|
|
|
+ editForm.value = { name: '', area: '', facilityType: '', time: '', pointCount: 0, points: [] }
|
|
|
|
|
+ editPoints.value = []
|
|
|
|
|
+ editMarkerCount.value = 0
|
|
|
editDialogVisible.value = true
|
|
editDialogVisible.value = true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -425,88 +432,70 @@ function handleEdit(row) {
|
|
|
editForm.value = {
|
|
editForm.value = {
|
|
|
name: row.name,
|
|
name: row.name,
|
|
|
area: row.area,
|
|
area: row.area,
|
|
|
|
|
+ facilityType: row.facilityType,
|
|
|
time: row.time,
|
|
time: row.time,
|
|
|
- gateCount: row.gateCount,
|
|
|
|
|
- storageCount: row.storageCount,
|
|
|
|
|
- pumpCount: row.pumpCount
|
|
|
|
|
|
|
+ pointCount: row.pointCount || 0,
|
|
|
|
|
+ points: []
|
|
|
}
|
|
}
|
|
|
- editMapTab.value = 'gate'
|
|
|
|
|
- // 深拷贝标记点数据
|
|
|
|
|
- editGatePoints.value = (row.gatePoints || []).map(p => ({ ...p }))
|
|
|
|
|
- editStoragePoints.value = (row.storagePoints || []).map(p => ({ ...p }))
|
|
|
|
|
- editPumpPoints.value = (row.pumpPoints || []).map(p => ({ ...p }))
|
|
|
|
|
- editGateMarkerCount.value = editGatePoints.value.length
|
|
|
|
|
- editStorageMarkerCount.value = editStoragePoints.value.length
|
|
|
|
|
- editPumpMarkerCount.value = editPumpPoints.value.length
|
|
|
|
|
|
|
+ const pts = parsePoints(row.points)
|
|
|
|
|
+ editPoints.value = pts.map(p => ({ ...p }))
|
|
|
|
|
+ editMarkerCount.value = editPoints.value.length
|
|
|
editDialogVisible.value = true
|
|
editDialogVisible.value = true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function handleEditClose() {
|
|
function handleEditClose() {
|
|
|
editDialogVisible.value = false
|
|
editDialogVisible.value = false
|
|
|
- if (editMapInstance) {
|
|
|
|
|
- editMapInstance = null
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (editMapInstance) { editMapInstance = null }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function onEditDialogOpened() {
|
|
function onEditDialogOpened() {
|
|
|
- setTimeout(() => {
|
|
|
|
|
- initEditMap()
|
|
|
|
|
- }, 300)
|
|
|
|
|
|
|
+ setTimeout(() => { initEditMap() }, 300)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function initEditMap() {
|
|
function initEditMap() {
|
|
|
const container = document.getElementById('gcssglEditMap')
|
|
const container = document.getElementById('gcssglEditMap')
|
|
|
if (!container) return
|
|
if (!container) return
|
|
|
-
|
|
|
|
|
try {
|
|
try {
|
|
|
editMapInstance = new BMapGL.Map('gcssglEditMap')
|
|
editMapInstance = new BMapGL.Map('gcssglEditMap')
|
|
|
const centerPoint = new BMapGL.Point(110.393, 28.452)
|
|
const centerPoint = new BMapGL.Point(110.393, 28.452)
|
|
|
editMapInstance.centerAndZoom(centerPoint, 15)
|
|
editMapInstance.centerAndZoom(centerPoint, 15)
|
|
|
editMapInstance.enableScrollWheelZoom(true)
|
|
editMapInstance.enableScrollWheelZoom(true)
|
|
|
|
|
|
|
|
- // 点击地图添加标记
|
|
|
|
|
editMapInstance.addEventListener('click', function (e) {
|
|
editMapInstance.addEventListener('click', function (e) {
|
|
|
addEditMarker(e.latlng)
|
|
addEditMarker(e.latlng)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- // 渲染已有标记
|
|
|
|
|
renderEditMarkers()
|
|
renderEditMarkers()
|
|
|
} catch (e) {
|
|
} catch (e) {
|
|
|
console.error('百度地图初始化失败:', e)
|
|
console.error('百度地图初始化失败:', e)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function getCurrentEditPointList() {
|
|
|
|
|
- if (editMapTab.value === 'gate') return editGatePoints.value
|
|
|
|
|
- if (editMapTab.value === 'storage') return editStoragePoints.value
|
|
|
|
|
- return editPumpPoints.value
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
function addEditMarker(point) {
|
|
function addEditMarker(point) {
|
|
|
- const tab = editMapTab.value
|
|
|
|
|
- let pointList, count, labelPrefix
|
|
|
|
|
-
|
|
|
|
|
- if (tab === 'gate') {
|
|
|
|
|
- pointList = editGatePoints.value
|
|
|
|
|
- count = ++editGateMarkerCount.value
|
|
|
|
|
- labelPrefix = '闸门'
|
|
|
|
|
- } else if (tab === 'storage') {
|
|
|
|
|
- pointList = editStoragePoints.value
|
|
|
|
|
- count = ++editStorageMarkerCount.value
|
|
|
|
|
- labelPrefix = '调蓄设施'
|
|
|
|
|
- } else {
|
|
|
|
|
- pointList = editPumpPoints.value
|
|
|
|
|
- count = ++editPumpMarkerCount.value
|
|
|
|
|
- labelPrefix = '泵站'
|
|
|
|
|
|
|
+ const facilityType = editForm.value.facilityType
|
|
|
|
|
+ if (!facilityType) {
|
|
|
|
|
+ ElMessage.warning('请先选择设施类型')
|
|
|
|
|
+ return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- pointList.push({
|
|
|
|
|
- name: `${labelPrefix}${count}`,
|
|
|
|
|
|
|
+ // 单点类型:再次点击重新定位
|
|
|
|
|
+ if (editPoints.value.length >= 1) {
|
|
|
|
|
+ editPoints.value[0] = {
|
|
|
|
|
+ name: editPoints.value[0].name,
|
|
|
|
|
+ lng: point.lng,
|
|
|
|
|
+ lat: point.lat
|
|
|
|
|
+ }
|
|
|
|
|
+ renderEditMarkers(false)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const count = ++editMarkerCount.value
|
|
|
|
|
+ editPoints.value.push({
|
|
|
|
|
+ name: `${facilityType}${count}`,
|
|
|
lng: point.lng,
|
|
lng: point.lng,
|
|
|
lat: point.lat
|
|
lat: point.lat
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- // 统一重绘,保证地图与数据完全一致
|
|
|
|
|
renderEditMarkers(false)
|
|
renderEditMarkers(false)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -514,7 +503,7 @@ function renderEditMarkers(shouldCenter = true) {
|
|
|
if (!editMapInstance) return
|
|
if (!editMapInstance) return
|
|
|
editMapInstance.clearOverlays()
|
|
editMapInstance.clearOverlays()
|
|
|
|
|
|
|
|
- const points = getCurrentEditPointList()
|
|
|
|
|
|
|
+ const points = editPoints.value
|
|
|
if (shouldCenter) {
|
|
if (shouldCenter) {
|
|
|
const center = points.length > 0
|
|
const center = points.length > 0
|
|
|
? new BMapGL.Point(points[0].lng, points[0].lat)
|
|
? new BMapGL.Point(points[0].lng, points[0].lat)
|
|
@@ -522,69 +511,63 @@ function renderEditMarkers(shouldCenter = true) {
|
|
|
editMapInstance.centerAndZoom(center, 15)
|
|
editMapInstance.centerAndZoom(center, 15)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ const colorMap = { '闸门': '#409eff', '调蓄设施': '#e6a23c', '泵站': '#67c23a' }
|
|
|
|
|
+ const color = colorMap[editForm.value.facilityType] || '#409eff'
|
|
|
|
|
+
|
|
|
points.forEach((point, index) => {
|
|
points.forEach((point, index) => {
|
|
|
const bPoint = new BMapGL.Point(point.lng, point.lat)
|
|
const bPoint = new BMapGL.Point(point.lng, point.lat)
|
|
|
- const label = createMapMarker(editMapInstance, bPoint, point.name)
|
|
|
|
|
|
|
+ const label = createMapMarker(editMapInstance, bPoint, point.name, color)
|
|
|
|
|
|
|
|
- // 右键删除标记
|
|
|
|
|
label.addEventListener('rightclick', () => {
|
|
label.addEventListener('rightclick', () => {
|
|
|
- const list = getCurrentEditPointList()
|
|
|
|
|
- list.splice(index, 1)
|
|
|
|
|
|
|
+ editPoints.value.splice(index, 1)
|
|
|
renderEditMarkers(false)
|
|
renderEditMarkers(false)
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function switchEditMapTab(tab) {
|
|
|
|
|
- editMapTab.value = tab
|
|
|
|
|
- renderEditMarkers()
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
function clearEditMarkers() {
|
|
function clearEditMarkers() {
|
|
|
- if (editMapTab.value === 'gate') {
|
|
|
|
|
- editGatePoints.value = []
|
|
|
|
|
- editGateMarkerCount.value = 0
|
|
|
|
|
- } else if (editMapTab.value === 'storage') {
|
|
|
|
|
- editStoragePoints.value = []
|
|
|
|
|
- editStorageMarkerCount.value = 0
|
|
|
|
|
- } else {
|
|
|
|
|
- editPumpPoints.value = []
|
|
|
|
|
- editPumpMarkerCount.value = 0
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ editPoints.value = []
|
|
|
|
|
+ editMarkerCount.value = 0
|
|
|
renderEditMarkers()
|
|
renderEditMarkers()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function handleEditSubmit() {
|
|
function handleEditSubmit() {
|
|
|
- editFormRef.value.validate(valid => {
|
|
|
|
|
|
|
+ editFormRef.value.validate(async valid => {
|
|
|
if (!valid) return
|
|
if (!valid) return
|
|
|
|
|
|
|
|
const formData = {
|
|
const formData = {
|
|
|
- ...editForm.value,
|
|
|
|
|
- gatePoints: editGatePoints.value.map(p => ({ ...p })),
|
|
|
|
|
- storagePoints: editStoragePoints.value.map(p => ({ ...p })),
|
|
|
|
|
- pumpPoints: editPumpPoints.value.map(p => ({ ...p })),
|
|
|
|
|
- gateCount: editGatePoints.value.length,
|
|
|
|
|
- storageCount: editStoragePoints.value.length,
|
|
|
|
|
- pumpCount: editPumpPoints.value.length
|
|
|
|
|
|
|
+ name: editForm.value.name,
|
|
|
|
|
+ area: editForm.value.area,
|
|
|
|
|
+ facilityType: editForm.value.facilityType,
|
|
|
|
|
+ time: editForm.value.time,
|
|
|
|
|
+ pointCount: editPoints.value.length,
|
|
|
|
|
+ points: JSON.stringify(editPoints.value.map(p => ({ name: p.name, lng: p.lng, lat: p.lat })))
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- if (isEditMode.value) {
|
|
|
|
|
- // 修改
|
|
|
|
|
- const index = tableData.value.findIndex(item => item.id === editRowId.value)
|
|
|
|
|
- if (index !== -1) {
|
|
|
|
|
- tableData.value[index] = { ...tableData.value[index], ...formData }
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (isEditMode.value) {
|
|
|
|
|
+ formData.id = editRowId.value
|
|
|
|
|
+ const res = await updateFacility(formData)
|
|
|
|
|
+ if (res.code === 0 || res.code === 200) {
|
|
|
|
|
+ ElMessage.success('修改成功')
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(res.msg || '修改失败')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const res = await addFacility(formData)
|
|
|
|
|
+ if (res.code === 0 || res.code === 200) {
|
|
|
|
|
+ ElMessage.success('新增成功')
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(res.msg || '新增失败')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- ElMessage.success('修改成功')
|
|
|
|
|
- } else {
|
|
|
|
|
- // 新增
|
|
|
|
|
- formData.id = nextId++
|
|
|
|
|
- tableData.value.push(formData)
|
|
|
|
|
- ElMessage.success('新增成功')
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- editDialogVisible.value = false
|
|
|
|
|
- if (editMapInstance) {
|
|
|
|
|
- editMapInstance = null
|
|
|
|
|
|
|
+ editDialogVisible.value = false
|
|
|
|
|
+ if (editMapInstance) { editMapInstance = null }
|
|
|
|
|
+ loadData()
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ console.error('提交失败', e)
|
|
|
|
|
+ ElMessage.error('操作失败')
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
@@ -595,13 +578,19 @@ function handleDelete(row) {
|
|
|
confirmButtonText: '确定',
|
|
confirmButtonText: '确定',
|
|
|
cancelButtonText: '取消',
|
|
cancelButtonText: '取消',
|
|
|
type: 'warning'
|
|
type: 'warning'
|
|
|
- }).then(() => {
|
|
|
|
|
- const index = tableData.value.findIndex(item => item.id === row.id)
|
|
|
|
|
- if (index !== -1) {
|
|
|
|
|
- tableData.value.splice(index, 1)
|
|
|
|
|
|
|
+ }).then(async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await deleteFacility(row.id)
|
|
|
|
|
+ if (res.code === 0 || res.code === 200) {
|
|
|
|
|
+ ElMessage.success('删除成功')
|
|
|
|
|
+ loadData()
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(res.msg || '删除失败')
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ ElMessage.error('删除失败')
|
|
|
}
|
|
}
|
|
|
- ElMessage.success('删除成功')
|
|
|
|
|
- }).catch(() => { })
|
|
|
|
|
|
|
+ }).catch(() => {})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function handleBatchDelete() {
|
|
function handleBatchDelete() {
|
|
@@ -610,104 +599,34 @@ function handleBatchDelete() {
|
|
|
confirmButtonText: '确定',
|
|
confirmButtonText: '确定',
|
|
|
cancelButtonText: '取消',
|
|
cancelButtonText: '取消',
|
|
|
type: 'warning'
|
|
type: 'warning'
|
|
|
- }).then(() => {
|
|
|
|
|
- tableData.value = tableData.value.filter(item => !selectedIds.value.includes(item.id))
|
|
|
|
|
- selectedIds.value = []
|
|
|
|
|
- ElMessage.success('删除成功')
|
|
|
|
|
- }).catch(() => { })
|
|
|
|
|
|
|
+ }).then(async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await Promise.all(selectedIds.value.map(id => deleteFacility(id)))
|
|
|
|
|
+ selectedIds.value = []
|
|
|
|
|
+ ElMessage.success('删除成功')
|
|
|
|
|
+ loadData()
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ ElMessage.error('删除失败')
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(() => {})
|
|
|
}
|
|
}
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
|
-.app-container {
|
|
|
|
|
- padding: 20px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.search-form {
|
|
|
|
|
- margin-bottom: 16px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.toolbar {
|
|
|
|
|
- margin-bottom: 16px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.detail-info {
|
|
|
|
|
- margin-bottom: 16px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.info-item {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- margin-bottom: 12px;
|
|
|
|
|
- line-height: 32px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.info-label {
|
|
|
|
|
- color: #909399;
|
|
|
|
|
- font-size: 14px;
|
|
|
|
|
- white-space: nowrap;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.info-value {
|
|
|
|
|
- color: #303133;
|
|
|
|
|
- font-size: 14px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.map-section {
|
|
|
|
|
- border: 1px solid #e4e7ed;
|
|
|
|
|
- border-radius: 4px;
|
|
|
|
|
- overflow: hidden;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.map-tabs {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- background: #f5f7fa;
|
|
|
|
|
- border-bottom: 1px solid #e4e7ed;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.map-tab {
|
|
|
|
|
- padding: 8px 24px;
|
|
|
|
|
- font-size: 14px;
|
|
|
|
|
- cursor: pointer;
|
|
|
|
|
- color: #606266;
|
|
|
|
|
- transition: all 0.3s;
|
|
|
|
|
- user-select: none;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.map-tab:hover {
|
|
|
|
|
- color: #409eff;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.map-tab.active {
|
|
|
|
|
- background: #409eff;
|
|
|
|
|
- color: #fff;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.map-tab-action {
|
|
|
|
|
- padding: 8px 24px;
|
|
|
|
|
- font-size: 14px;
|
|
|
|
|
- cursor: pointer;
|
|
|
|
|
- color: #f56c6c;
|
|
|
|
|
- transition: all 0.3s;
|
|
|
|
|
- user-select: none;
|
|
|
|
|
- margin-left: auto;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.map-tab-action:hover {
|
|
|
|
|
- color: #f78989;
|
|
|
|
|
- text-decoration: underline;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.map-container {
|
|
|
|
|
- width: 100%;
|
|
|
|
|
- height: 400px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.marker-count {
|
|
|
|
|
- padding: 8px 16px;
|
|
|
|
|
- font-size: 13px;
|
|
|
|
|
- color: #909399;
|
|
|
|
|
- background: #f5f7fa;
|
|
|
|
|
- border-top: 1px solid #e4e7ed;
|
|
|
|
|
-}
|
|
|
|
|
|
|
+.app-container { padding: 20px; }
|
|
|
|
|
+.search-form { margin-bottom: 16px; }
|
|
|
|
|
+.toolbar { margin-bottom: 16px; }
|
|
|
|
|
+.detail-info { margin-bottom: 16px; }
|
|
|
|
|
+.info-item { display: flex; align-items: center; margin-bottom: 12px; line-height: 32px; }
|
|
|
|
|
+.info-label { color: #909399; font-size: 14px; white-space: nowrap; }
|
|
|
|
|
+.info-value { color: #303133; font-size: 14px; }
|
|
|
|
|
+.map-section { border: 1px solid #e4e7ed; border-radius: 4px; overflow: hidden; }
|
|
|
|
|
+.map-tabs { display: flex; background: #f5f7fa; border-bottom: 1px solid #e4e7ed; }
|
|
|
|
|
+.map-tab { padding: 8px 24px; font-size: 14px; cursor: pointer; color: #606266; transition: all 0.3s; user-select: none; }
|
|
|
|
|
+.map-tab:hover { color: #409eff; }
|
|
|
|
|
+.map-tab.active { background: #409eff; color: #fff; }
|
|
|
|
|
+.map-tab-action { padding: 8px 24px; font-size: 14px; cursor: pointer; color: #f56c6c; transition: all 0.3s; user-select: none; margin-left: auto; }
|
|
|
|
|
+.map-tab-action:hover { color: #f78989; text-decoration: underline; }
|
|
|
|
|
+.map-container { width: 100%; height: 400px; }
|
|
|
|
|
+.marker-count { padding: 8px 16px; font-size: 13px; color: #909399; background: #f5f7fa; border-top: 1px solid #e4e7ed; }
|
|
|
</style>
|
|
</style>
|