| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885 |
- <template>
- <div class="app-container">
- <!-- GIS 地图展示区 -->
- <div class="map-section" style="margin-bottom: 16px;">
- <div class="map-tabs">
- <div class="map-tab active">易积水点分布</div>
- </div>
- <div id="yjsdglMainMap" class="map-container" style="height: 350px;"></div>
- </div>
- <!-- 搜索区域 -->
- <el-form :model="queryParams" ref="queryRef" :inline="true" class="search-form">
- <el-form-item label="点位名称">
- <el-input v-model="queryParams.name" placeholder="请输入" clearable style="width: 200px" />
- </el-form-item>
- <el-form-item label="地点">
- <el-input v-model="queryParams.area" placeholder="请输入" clearable style="width: 200px" />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleQuery">搜索</el-button>
- </el-form-item>
- </el-form>
- <!-- 操作按钮区域 -->
- <div class="toolbar">
- <el-button type="primary" @click="handleAdd">新增</el-button>
- <el-button type="danger" :disabled="selectedIds.length === 0" @click="handleBatchDelete">删除</el-button>
- </div>
- <!-- 数据表格 -->
- <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 label="监测点名称" prop="name" min-width="160" />
- <el-table-column label="地点" prop="area" min-width="100" />
- <el-table-column label="数据时间" prop="time" min-width="120" />
- <el-table-column label="易积水点数量" prop="waterloggingCount" min-width="100" />
- <el-table-column label="积水量" prop="waterVolume" min-width="100" />
- <el-table-column label="积水程度" min-width="120">
- <template #default="{ row }">D:\work1\city-life-line\src\views\subSystem\drainage\DrainageWorkOrder.vue
- <el-tag :type="getWaterloggingLevelType(row.waterloggingLevel)" size="small">
- {{ getWaterloggingLevelLabel(row.waterloggingLevel) }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="关联设备" min-width="160">
- <template #default="{ row }">
- {{ equipmentNameMap[row.id] || '' }}
- </template>
- </el-table-column>
- <el-table-column label="操作" width="240" align="center">
- <template #default="{ row }">
- <el-button link type="primary" @click="handleView(row)">查看</el-button>
- <el-button link type="primary" @click="handleEdit(row)">修改</el-button>
- <el-button link type="primary" @click="handleBind(row)">关联设备</el-button>
- <el-button link type="danger" @click="handleDelete(row)">删除</el-button>
- </template>
- </el-table-column>
- </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">
- <div class="detail-info">
- <el-row :gutter="20">
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">监测点名称:</span>
- <span class="info-value">{{ currentRow.name }}</span>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">地点:</span>
- <span class="info-value">{{ currentRow.area }}</span>
- </div>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">数据时间:</span>
- <span class="info-value">{{ currentRow.time }}</span>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">易积水点数量:</span>
- <span class="info-value">{{ currentRow.waterloggingPoints.length }}</span>
- </div>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">积水量:</span>
- <span class="info-value">{{ currentRow.waterVolume }}</span>
- </div>
- </el-col>
- <el-col :span="12">
- <div class="info-item">
- <span class="info-label">积水程度:</span>
- <span class="info-value">
- <el-tag :type="getWaterloggingLevelType(currentRow.waterloggingLevel)" size="small">
- {{ getWaterloggingLevelLabel(currentRow.waterloggingLevel) }}
- </el-tag>
- </span>
- </div>
- </el-col>
- </el-row>
- </div>
- <!-- 关联设备 -->
- <div v-if="viewEquipmentNames.length" class="detail-info" style="margin-top: 12px;">
- <el-row :gutter="20">
- <el-col :span="24">
- <div class="info-item">
- <span class="info-label">关联设备:</span>
- <span class="info-value">{{ viewEquipmentNames.join('、') }}</span>
- </div>
- </el-col>
- </el-row>
- </div>
- <!-- 地图区域 -->
- <div class="map-section">
- <div id="yjsdglViewMap" class="map-container"></div>
- </div>
- </el-dialog>
- <!-- 新增/修改对话框 -->
- <el-dialog v-model="editDialogVisible" :title="editDialogTitle" width="800px" :before-close="handleEditClose"
- @opened="onEditDialogOpened">
- <el-form ref="editFormRef" :model="editForm" :rules="editRules" label-width="100px">
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="监测点名称" prop="name">
- <el-input v-model="editForm.name" placeholder="请输入监测点名称" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="地点" prop="area">
- <el-input v-model="editForm.area" placeholder="请输入地点" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="数据时间" prop="time">
- <el-date-picker v-model="editForm.time" type="date" placeholder="请选择日期" value-format="YYYY-MM-DD"
- style="width: 100%" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="易积水点数量">
- <el-input :model-value="editWaterloggingPoints.length" disabled />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item label="积水量" prop="waterVolume">
- <el-input v-model="editForm.waterVolume" type="number" placeholder="请输入积水量" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="积水程度" prop="waterloggingLevel">
- <el-select v-model="editForm.waterloggingLevel" placeholder="请选择积水程度" style="width: 100%">
- <el-option label="未积水" :value="0" />
- <el-option label="轻度积水" :value="1" />
- <el-option label="中度积水" :value="2" />
- <el-option label="严重积水" :value="3" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <!-- 地图标点区域 -->
- <div class="map-section" style="margin-top: 16px;">
- <div class="map-tabs">
- <div class="map-tab active">易积水点</div>
- <div class="map-tab-action" @click="clearEditMarkers">清除所有标记</div>
- </div>
- <div id="yjsdglEditMap" class="map-container" style="height: 350px;"></div>
- <div class="marker-count">
- 已标记 {{ editWaterloggingPoints.length }} 个易积水点
- </div>
- </div>
- <template #footer>
- <el-button @click="handleEditClose">取 消</el-button>
- <el-button type="primary" @click="handleEditSubmit">确 定</el-button>
- </template>
- </el-dialog>
- <!-- 关联设备弹框 -->
- <el-dialog v-model="bindDialogVisible" title="关联设备" width="700px" @close="closeBindDialog">
- <el-form :inline="true" :model="bindQueryParams" style="margin-bottom: 12px;">
- <el-form-item label="设备名称">
- <el-input v-model="bindQueryParams.equipmentName" placeholder="请输入设备名称" clearable />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleBindQuery">搜索</el-button>
- </el-form-item>
- </el-form>
- <el-table v-loading="bindLoading" :data="bindTableData" border row-key="equipmentId"
- @selection-change="handleBindSelectionChange" ref="bindTableRef">
- <el-table-column type="selection" width="55" align="center" :reserve-selection="true" />
- <el-table-column label="设备名称" prop="equipmentName" min-width="120" />
- <el-table-column label="设备编号" prop="equipmentCode" min-width="120" />
- <el-table-column label="设备类型" prop="equipmentTypeName" min-width="100" />
- <el-table-column label="安装位置" prop="installLocation" min-width="120" />
- </el-table>
- <el-pagination v-model:current-page="bindPageNum" v-model:page-size="bindPageSize" :total="bindTotal"
- :page-sizes="[10, 20, 50]" layout="total, sizes, prev, pager, next, jumper"
- style="margin-top: 12px; justify-content: flex-end;" @size-change="loadBindData" @current-change="loadBindData" />
- <template #footer>
- <el-button @click="closeBindDialog">取 消</el-button>
- <el-button type="primary" @click="submitBind">确 定</el-button>
- </template>
- </el-dialog>
- </div>
- </template>
- <script setup name="Yjsdgl">
- import { ref, computed, nextTick, onMounted } from 'vue'
- import { ElMessage, ElMessageBox } from 'element-plus'
- import locationIcon from '@/assets/images/location.png'
- import {
- getWaterloggingPage,
- addWaterlogging,
- updateWaterlogging,
- deleteWaterlogging,
- getEquipmentPage,
- getEquipmentById,
- bindWaterloggingEquipment
- } from '@/api/drainage'
- // 地图标记创建(用Label+img代替Marker)
- function createMapMarker(map, bPoint, name) {
- 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><img src="${locationIcon}" style="width:28px;height:28px;display:block;margin:0 auto;"/></div>
- </div>`
- const label = new BMapGL.Label(html, {
- position: bPoint,
- offset: new BMapGL.Size(-30, -50)
- })
- label.setStyle({
- border: 'none',
- background: 'transparent',
- padding: '0'
- })
- map.addOverlay(label)
- return label
- }
- // 积水程度选项
- const waterloggingLevelOptions = [
- { value: 0, label: '未积水', type: 'success' },
- { value: 1, label: '轻度积水', type: 'info' },
- { value: 2, label: '中度积水', type: 'warning' },
- { value: 3, label: '严重积水', type: 'danger' }
- ]
- function getWaterloggingLevelLabel(level) {
- const option = waterloggingLevelOptions.find(item => item.value === level)
- return option ? option.label : '未知'
- }
- function getWaterloggingLevelType(level) {
- const option = waterloggingLevelOptions.find(item => item.value === level)
- return option ? option.type : 'info'
- }
- // 安全解析 waterloggingPoints(后端返回 JSON 字符串,需转为数组使用)
- function parseWaterloggingPoints(raw) {
- if (!raw) return []
- if (Array.isArray(raw)) return raw
- if (typeof raw === 'string') {
- try {
- const parsed = JSON.parse(raw)
- return Array.isArray(parsed) ? parsed : []
- } catch (e) {
- console.warn('waterloggingPoints JSON 解析失败:', raw, e)
- return []
- }
- }
- return []
- }
- // ==================== 搜索参数 ====================
- const queryParams = ref({
- name: '',
- area: ''
- })
- // ==================== 表格数据 ====================
- 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 getWaterloggingPage(pageNum.value, pageSize.value, queryParams.value)
- // 兼容直接返回Page对象(无code包装)和AjaxResult包装两种格式
- const pageData = res.code !== undefined ? res.data : res
- tableData.value = pageData.records || []
- total.value = pageData.total || 0
- renderMainMapMarkers()
- resolveEquipmentNames()
- } catch (e) {
- console.error('加载易积水点数据失败', e)
- } finally {
- loading.value = false
- }
- }
- // 关联设备名称映射
- const equipmentNameMap = ref({})
- async function resolveEquipmentNames() {
- const map = {}
- for (const row of tableData.value) {
- if (row.equipmentId) {
- const ids = row.equipmentId.split(',')
- const names = []
- for (const id of ids) {
- try {
- const res = await getEquipmentById(id.trim())
- const data = res.code !== undefined ? res.data : res
- const info = data && data.equipmentInfo ? data.equipmentInfo : data
- if (info && info.equipmentName) names.push(info.equipmentName)
- } catch (e) { /* skip */ }
- }
- map[row.id] = names.join('、')
- }
- }
- equipmentNameMap.value = map
- }
- onMounted(() => {
- loadData()
- setTimeout(() => { initMainMap() }, 500)
- })
- // ==================== 顶部主地图 ====================
- let mainMapInstance = null
- function initMainMap() {
- const container = document.getElementById('yjsdglMainMap')
- if (!container) return
- try {
- mainMapInstance = new BMapGL.Map('yjsdglMainMap')
- 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 = []
- tableData.value.forEach(row => {
- const points = parseWaterloggingPoints(row.waterloggingPoints)
- points.forEach(p => {
- if (p.lng && p.lat) {
- const bPoint = new BMapGL.Point(p.lng, p.lat)
- createMapMarker(mainMapInstance, bPoint, p.name || row.name)
- allPoints.push(bPoint)
- }
- })
- })
- if (allPoints.length > 0) {
- mainMapInstance.setViewport(allPoints)
- }
- }
- // 多选
- const selectedIds = ref([])
- function handleSelectionChange(selection) {
- selectedIds.value = selection.map(item => item.id)
- }
- // 表格数据直接用 tableData(已是分页数据)
- const filteredList = computed(() => tableData.value)
- // 搜索
- function handleQuery() {
- pageNum.value = 1
- loadData()
- }
- // ==================== 查看详情对话框 ====================
- const dialogVisible = ref(false)
- const currentRow = ref({})
- const viewEquipmentNames = ref([])
- let viewMapInstance = null
- async function handleView(row) {
- currentRow.value = {
- ...row,
- // 将 JSON 字符串解析为数组,供模板和地图渲染使用
- waterloggingPoints: parseWaterloggingPoints(row.waterloggingPoints)
- }
- dialogVisible.value = true
- viewEquipmentNames.value = []
- if (row.equipmentId) {
- const ids = row.equipmentId.split(',')
- const names = []
- for (const id of ids) {
- try {
- const res = await getEquipmentById(id.trim())
- const data = res.code !== undefined ? res.data : res
- const info = data && data.equipmentInfo ? data.equipmentInfo : data
- if (info && info.equipmentName) names.push(info.equipmentName)
- } catch (e) { /* skip */ }
- }
- viewEquipmentNames.value = names
- }
- }
- function handleClose() {
- dialogVisible.value = false
- if (viewMapInstance) {
- viewMapInstance = null
- }
- }
- function onDialogOpened() {
- setTimeout(() => {
- initViewMap()
- }, 300)
- }
- function initViewMap() {
- const container = document.getElementById('yjsdglViewMap')
- if (!container) return
- try {
- viewMapInstance = new BMapGL.Map('yjsdglViewMap')
- const centerPoint = new BMapGL.Point(110.393, 28.452)
- viewMapInstance.centerAndZoom(centerPoint, 15)
- viewMapInstance.enableScrollWheelZoom(true)
- renderViewMarkers()
- } catch (e) {
- console.error('百度地图初始化失败:', e)
- }
- }
- function renderViewMarkers() {
- if (!viewMapInstance) return
- viewMapInstance.clearOverlays()
- const points = currentRow.value.waterloggingPoints || []
- points.forEach(point => {
- const bPoint = new BMapGL.Point(point.lng, point.lat)
- createMapMarker(viewMapInstance, bPoint, point.name)
- })
- if (points.length > 0) {
- const viewPoints = points.map(p => new BMapGL.Point(p.lng, p.lat))
- viewMapInstance.setViewport(viewPoints)
- }
- }
- // ==================== 新增/修改对话框 ====================
- const editDialogVisible = ref(false)
- const editDialogTitle = ref('新增监测点')
- const editFormRef = ref(null)
- const isEditMode = ref(false)
- const editRowId = ref(null)
- const editForm = ref({
- name: '',
- area: '',
- time: '',
- waterVolume: null,
- waterloggingLevel: 0
- })
- const editRules = {
- name: [{ required: true, message: '请输入监测点名称', trigger: 'blur' }],
- area: [{ required: true, message: '请输入地点', trigger: 'blur' }],
- time: [{ required: true, message: '请选择数据时间', trigger: 'change' }]
- }
- // 编辑弹窗地图相关
- let editMapInstance = null
- let editWaterloggingPoints = ref([])
- let editWaterloggingMarkerCount = ref(0)
- function handleAdd() {
- isEditMode.value = false
- editDialogTitle.value = '新增监测点'
- editRowId.value = null
- editForm.value = {
- name: '',
- area: '',
- time: '',
- waterVolume: null,
- waterloggingLevel: 0
- }
- editWaterloggingPoints.value = []
- editWaterloggingMarkerCount.value = 0
- editDialogVisible.value = true
- }
- function handleEdit(row) {
- isEditMode.value = true
- editDialogTitle.value = '修改监测点'
- editRowId.value = row.id
- editForm.value = {
- name: row.name,
- area: row.area,
- time: row.time,
- waterVolume: row.waterVolume,
- waterloggingLevel: row.waterloggingLevel ?? 0
- }
- // 深拷贝标记点数据(waterloggingPoints 从后端返回为 JSON 字符串,需先解析为数组)
- editWaterloggingPoints.value = parseWaterloggingPoints(row.waterloggingPoints).map(p => ({ ...p }))
- editWaterloggingMarkerCount.value = editWaterloggingPoints.value.length
- editDialogVisible.value = true
- }
- function handleEditClose() {
- editDialogVisible.value = false
- if (editMapInstance) {
- editMapInstance = null
- }
- }
- function onEditDialogOpened() {
- setTimeout(() => {
- initEditMap()
- }, 300)
- }
- function initEditMap() {
- const container = document.getElementById('yjsdglEditMap')
- if (!container) return
- try {
- editMapInstance = new BMapGL.Map('yjsdglEditMap')
- const centerPoint = new BMapGL.Point(110.393, 28.452)
- editMapInstance.centerAndZoom(centerPoint, 15)
- editMapInstance.enableScrollWheelZoom(true)
- // 点击地图添加标记
- editMapInstance.addEventListener('click', function (e) {
- addEditMarker(e.latlng)
- })
- // 渲染已有标记
- renderEditMarkers()
- } catch (e) {
- console.error('百度地图初始化失败:', e)
- }
- }
- function addEditMarker(point) {
- // 只能标记一个点位,再次点击重新定位
- if (editWaterloggingPoints.value.length >= 1) {
- editWaterloggingPoints.value[0] = {
- name: editWaterloggingPoints.value[0].name,
- lng: point.lng,
- lat: point.lat
- }
- renderEditMarkers(false)
- return
- }
- const count = ++editWaterloggingMarkerCount.value
- editWaterloggingPoints.value.push({
- name: `易积水点${count}`,
- lng: point.lng,
- lat: point.lat
- })
- // 统一重绘,保证地图与数据完全一致
- renderEditMarkers(false)
- }
- function renderEditMarkers(shouldCenter = true) {
- if (!editMapInstance) return
- editMapInstance.clearOverlays()
- const points = editWaterloggingPoints.value
- if (shouldCenter) {
- const center = points.length > 0
- ? new BMapGL.Point(points[0].lng, points[0].lat)
- : new BMapGL.Point(110.393, 28.452)
- editMapInstance.centerAndZoom(center, 15)
- }
- points.forEach((point, index) => {
- const bPoint = new BMapGL.Point(point.lng, point.lat)
- const label = createMapMarker(editMapInstance, bPoint, point.name)
- // 右键删除标记
- label.addEventListener('rightclick', () => {
- editWaterloggingPoints.value.splice(index, 1)
- renderEditMarkers(false)
- })
- })
- }
- function clearEditMarkers() {
- editWaterloggingPoints.value = []
- editWaterloggingMarkerCount.value = 0
- renderEditMarkers()
- }
- function handleEditSubmit() {
- editFormRef.value.validate(async valid => {
- if (!valid) return
- const formData = {
- name: editForm.value.name,
- area: editForm.value.area,
- time: editForm.value.time,
- waterVolume: editForm.value.waterVolume,
- waterloggingLevel: editForm.value.waterloggingLevel,
- waterloggingCount: editWaterloggingPoints.value.length,
- waterloggingPoints: JSON.stringify(editWaterloggingPoints.value.map(p => ({ name: p.name, lng: p.lng, lat: p.lat })))
- }
- try {
- if (isEditMode.value) {
- formData.id = editRowId.value
- const res = await updateWaterlogging(formData)
- if (res.code === 0 || res.code === 200) {
- ElMessage.success('修改成功')
- } else {
- ElMessage.error(res.msg || '修改失败')
- return
- }
- } else {
- const res = await addWaterlogging(formData)
- if (res.code === 0 || res.code === 200) {
- ElMessage.success('新增成功')
- } else {
- ElMessage.error(res.msg || '新增失败')
- return
- }
- }
- editDialogVisible.value = false
- if (editMapInstance) {
- editMapInstance = null
- }
- loadData()
- } catch (e) {
- console.error('提交失败', e)
- ElMessage.error('操作失败')
- }
- })
- }
- // ==================== 删除功能 ====================
- function handleDelete(row) {
- ElMessageBox.confirm(`确认删除监测点"${row.name}"吗?`, '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(async () => {
- try {
- const res = await deleteWaterlogging(row.id)
- if (res.code === 0 || res.code === 200) {
- ElMessage.success('删除成功')
- loadData()
- } else {
- ElMessage.error(res.msg || '删除失败')
- }
- } catch (e) {
- ElMessage.error('删除失败')
- }
- }).catch(() => { })
- }
- function handleBatchDelete() {
- if (selectedIds.value.length === 0) return
- ElMessageBox.confirm(`确认删除选中的 ${selectedIds.value.length} 条数据吗?`, '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(async () => {
- try {
- await Promise.all(selectedIds.value.map(id => deleteWaterlogging(id)))
- selectedIds.value = []
- ElMessage.success('删除成功')
- loadData()
- } catch (e) {
- ElMessage.error('删除失败')
- }
- }).catch(() => { })
- }
- // ==================== 关联设备 ====================
- const bindDialogVisible = ref(false)
- const bindLoading = ref(false)
- const bindTableData = ref([])
- const bindTotal = ref(0)
- const bindPageNum = ref(1)
- const bindPageSize = ref(10)
- const bindQueryParams = ref({ equipmentName: '', equipmentTypeId: 'drainage' })
- const selectedEquipmentIds = ref([])
- const currentPartitionId = ref('')
- const bindTableRef = ref(null)
- function handleBind(row) {
- currentPartitionId.value = row.id
- bindDialogVisible.value = true
- bindPageNum.value = 1
- bindQueryParams.value.equipmentName = ''
- if (row.equipmentId) {
- selectedEquipmentIds.value = row.equipmentId.split(',')
- } else {
- selectedEquipmentIds.value = []
- }
- nextTick(() => {
- loadBindData()
- })
- }
- function handleBindQuery() {
- bindPageNum.value = 1
- loadBindData()
- }
- async function loadBindData() {
- bindLoading.value = true
- try {
- const res = await getEquipmentPage(bindPageNum.value, bindPageSize.value, bindQueryParams.value)
- const pageData = res.code !== undefined ? res.data : res
- bindTableData.value = pageData.records || []
- bindTotal.value = pageData.total || 0
- await nextTick()
- if (selectedEquipmentIds.value.length > 0 && bindTableRef.value) {
- bindTableData.value.forEach(row => {
- if (selectedEquipmentIds.value.includes(row.equipmentId)) {
- bindTableRef.value.toggleRowSelection(row, true)
- }
- })
- }
- } catch (e) {
- console.error('加载设备列表失败', e)
- } finally {
- bindLoading.value = false
- }
- }
- function handleBindSelectionChange(selection) {
- selectedEquipmentIds.value = selection.map(item => item.equipmentId)
- }
- function closeBindDialog() {
- bindDialogVisible.value = false
- bindTableData.value = []
- selectedEquipmentIds.value = []
- }
- async function submitBind() {
- if (selectedEquipmentIds.value.length === 0) {
- ElMessage.warning('请选择要关联的设备')
- return
- }
- try {
- const res = await bindWaterloggingEquipment({
- partitionId: currentPartitionId.value,
- equipmentIds: selectedEquipmentIds.value
- })
- if (res.code === 0 || res.code === 200) {
- ElMessage.success('关联成功')
- closeBindDialog()
- loadData()
- } else {
- ElMessage.error(res.msg || '关联失败')
- }
- } catch (e) {
- console.error('关联设备失败', e)
- ElMessage.error('关联失败')
- }
- }
- </script>
- <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: default;
- color: #fff;
- background: #409eff;
- user-select: none;
- }
- .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>
|