|
@@ -40,7 +40,7 @@
|
|
|
<el-form :inline="true" :model="searchForm" class="search-form">
|
|
<el-form :inline="true" :model="searchForm" class="search-form">
|
|
|
<el-form-item label="管网ID">
|
|
<el-form-item label="管网ID">
|
|
|
<el-select v-model="searchForm.networkId" placeholder="请选择" clearable style="width:190px" @change="onFilterChange">
|
|
<el-select v-model="searchForm.networkId" placeholder="请选择" clearable style="width:190px" @change="onFilterChange">
|
|
|
- <el-option v-for="p in pipelineData" :key="p.id" :label="p.id + ' - ' + p.name" :value="p.id" />
|
|
|
|
|
|
|
+ <el-option v-for="n in networkOptions" :key="n.networkId" :label="`${n.networkName}(${n.networkCode})`" :value="n.networkId" />
|
|
|
</el-select>
|
|
</el-select>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item label="维修类型">
|
|
<el-form-item label="维修类型">
|
|
@@ -59,8 +59,10 @@
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
- <el-table :data="paginatedData" border stripe v-loading="loading" max-height="380" size="small">
|
|
|
|
|
- <el-table-column prop="networkId" label="管网ID" width="100" />
|
|
|
|
|
|
|
+ <el-table :data="tableData" border stripe v-loading="loading" max-height="380" size="small">
|
|
|
|
|
+ <el-table-column label="管网" width="130">
|
|
|
|
|
+ <template #default="{ row }">{{ getNetworkName(row.networkId) }}</template>
|
|
|
|
|
+ </el-table-column>
|
|
|
<el-table-column prop="repairDate" label="维修日期" width="120" />
|
|
<el-table-column prop="repairDate" label="维修日期" width="120" />
|
|
|
<el-table-column prop="repairType" label="维修类型" width="120">
|
|
<el-table-column prop="repairType" label="维修类型" width="120">
|
|
|
<template #default="{ row }">{{ getDictLabel(repairTypeDict, row.repairType) }}</template>
|
|
<template #default="{ row }">{{ getDictLabel(repairTypeDict, row.repairType) }}</template>
|
|
@@ -80,6 +82,7 @@
|
|
|
<el-pagination
|
|
<el-pagination
|
|
|
v-model:current-page="pageNum" v-model:page-size="pageSize" :total="total"
|
|
v-model:current-page="pageNum" v-model:page-size="pageSize" :total="total"
|
|
|
layout="total, prev, pager, next, sizes" :page-sizes="[10, 20, 50]"
|
|
layout="total, prev, pager, next, sizes" :page-sizes="[10, 20, 50]"
|
|
|
|
|
+ @size-change="() => { pageNum = 1; loadData() }" @current-change="() => loadData()"
|
|
|
style="margin-top:16px;justify-content:flex-end"
|
|
style="margin-top:16px;justify-content:flex-end"
|
|
|
/>
|
|
/>
|
|
|
</el-card>
|
|
</el-card>
|
|
@@ -89,7 +92,7 @@
|
|
|
<el-form :model="formData" ref="formRef" label-width="100px">
|
|
<el-form :model="formData" ref="formRef" label-width="100px">
|
|
|
<el-form-item label="管网ID" prop="networkId">
|
|
<el-form-item label="管网ID" prop="networkId">
|
|
|
<el-select v-model="formData.networkId" style="width:100%">
|
|
<el-select v-model="formData.networkId" style="width:100%">
|
|
|
- <el-option v-for="p in pipelineData" :key="p.id" :label="p.id + ' - ' + p.name" :value="p.id" />
|
|
|
|
|
|
|
+ <el-option v-for="n in networkOptions" :key="n.networkId" :label="`${n.networkName}(${n.networkCode})`" :value="n.networkId" />
|
|
|
</el-select>
|
|
</el-select>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item label="维修日期" prop="repairDate">
|
|
<el-form-item label="维修日期" prop="repairDate">
|
|
@@ -119,11 +122,13 @@ import { computed, nextTick, onBeforeUnmount, onMounted, reactive, ref } from 'v
|
|
|
import * as echarts from 'echarts'
|
|
import * as echarts from 'echarts'
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
import { convertCoord } from '@/utils/coordTransform'
|
|
import { convertCoord } from '@/utils/coordTransform'
|
|
|
|
|
+import { getPipeNetworkOptions, getRepairRecordPage, addRepairRecord, updateRepairRecord, deleteRepairRecord } from '@/api/pipeNetwork/basic'
|
|
|
|
|
|
|
|
-// ==================== 静态数据 ====================
|
|
|
|
|
|
|
+// ==================== 数据 ====================
|
|
|
const loading = ref(false)
|
|
const loading = ref(false)
|
|
|
const pageNum = ref(1)
|
|
const pageNum = ref(1)
|
|
|
const pageSize = ref(10)
|
|
const pageSize = ref(10)
|
|
|
|
|
+const total = ref(0)
|
|
|
const searchForm = reactive({ networkId: '', repairType: '' })
|
|
const searchForm = reactive({ networkId: '', repairType: '' })
|
|
|
const dialogVisible = ref(false)
|
|
const dialogVisible = ref(false)
|
|
|
const dialogTitle = ref('新增')
|
|
const dialogTitle = ref('新增')
|
|
@@ -151,6 +156,7 @@ const MAP_MAX_ZOOM = 19
|
|
|
const MAP_DEFAULT_ZOOM = 15
|
|
const MAP_DEFAULT_ZOOM = 15
|
|
|
|
|
|
|
|
const mapError = ref('')
|
|
const mapError = ref('')
|
|
|
|
|
+const networkOptions = ref([])
|
|
|
let mapInstance = null
|
|
let mapInstance = null
|
|
|
let activeInfoWindow = null
|
|
let activeInfoWindow = null
|
|
|
let overlayClicked = false
|
|
let overlayClicked = false
|
|
@@ -175,42 +181,34 @@ const pipePointData = [
|
|
|
{ name: 'G点', lng: 110.370581, lat: 28.438198, pipelineId: 'net001' },
|
|
{ name: 'G点', lng: 110.370581, lat: 28.438198, pipelineId: 'net001' },
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
-// ==================== 维修记录 ====================
|
|
|
|
|
-const tableData = ref([
|
|
|
|
|
- { repairId: '1', networkId: 'net001', repairDate: '2026-06-10', repairType: '1', repairContent: '辰州北路高压段焊缝渗漏,管道焊接接头处出现裂纹,停气抢修并更换受损管段1.2m', repairCompany: '沅陵燃气工程有限公司', repairCost: 12500, repairPerson: '张建国', createTime: '2026-06-10 14:30:22', remark: '夜间施工,影响200户居民用气3小时' },
|
|
|
|
|
- { repairId: '2', networkId: 'net005', repairDate: '2026-06-05', repairType: '3', repairContent: '古城中路中压A段防腐层老化脱落,管体局部锈蚀深度1.8mm,防腐层整体修复', repairCompany: '湖南城市燃气技术公司', repairCost: 38600, repairPerson: '李志强', createTime: '2026-06-05 09:15:40', remark: '修复长度约85m' },
|
|
|
|
|
- { repairId: '3', networkId: 'net008', repairDate: '2026-05-28', repairType: '4', repairContent: '迎宾西路中压段三通管件更换,原管件因地基沉降导致应力开裂,更换为加强型管件', repairCompany: '怀化兴燃工程有限公司', repairCost: 8200, repairPerson: '王立新', createTime: '2026-05-28 16:45:10', remark: '' },
|
|
|
|
|
- { repairId: '4', networkId: 'net012', repairDate: '2026-05-20', repairType: '1', repairContent: '建设路中段第三方施工破坏,DN110 PE管被挖掘机铲断,紧急停气抢修', repairCompany: '沅陵燃气工程有限公司', repairCost: 15000, repairPerson: '赵明辉', createTime: '2026-05-20 03:22:55', remark: '第三方施工未报备' },
|
|
|
|
|
- { repairId: '5', networkId: 'net003', repairDate: '2026-05-15', repairType: '2', repairContent: '辰州中路高压B段计划停气检修,更换老化阀门2台,管道内检测并清管', repairCompany: '湖南省特种设备检测院', repairCost: 52000, repairPerson: '刘伟东', createTime: '2026-05-15 08:00:00', remark: '年度计划检修,提前72小时通知用户' },
|
|
|
|
|
- { repairId: '6', networkId: 'net009', repairDate: '2026-05-08', repairType: '5', repairContent: '县政府迎宾路中压段环焊缝异常,超声检测发现焊缝内部缺陷,焊缝重新焊接', repairCompany: '湖南城市燃气技术公司', repairCost: 18600, repairPerson: '李志强', createTime: '2026-05-08 11:20:18', remark: '焊缝缺陷深度2.3mm' },
|
|
|
|
|
- { repairId: '7', networkId: 'net015', repairDate: '2026-04-30', repairType: '6', repairContent: '滨江路东低压段阀门操作卡涩,阀杆填料泄漏,拆解阀门更换填料及O型密封圈', repairCompany: '怀化兴燃工程有限公司', repairCost: 4500, repairPerson: '王立新', createTime: '2026-04-30 14:10:33', remark: '' },
|
|
|
|
|
- { repairId: '8', networkId: 'net011', repairDate: '2026-04-22', repairType: '3', repairContent: '建设西路中压段管道外防腐层破损,杂散电流干扰导致电化学腐蚀,修复防腐层并加装牺牲阳极', repairCompany: '湖南城市燃气技术公司', repairCost: 28500, repairPerson: '李志强', createTime: '2026-04-22 10:05:00', remark: '腐蚀深度1.5mm' },
|
|
|
|
|
- { repairId: '9', networkId: 'net002', repairDate: '2026-04-15', repairType: '1', repairContent: '辰州中路高压A段管道泄漏报警,法兰连接处密封垫老化泄漏,紧急更换金属缠绕垫', repairCompany: '沅陵燃气工程有限公司', repairCost: 6300, repairPerson: '张建国', createTime: '2026-04-15 21:08:42', remark: '泄漏量约0.3m³' },
|
|
|
|
|
- { repairId: '10', networkId: 'net006', repairDate: '2026-04-08', repairType: '2', repairContent: '古城中路中压B段年度维护,全线管道壁厚检测,阴极保护系统检测,更换测试桩3个', repairCompany: '湖南省特种设备检测院', repairCost: 22000, repairPerson: '刘伟东', createTime: '2026-04-08 09:00:00', remark: '壁厚检测结果符合GB50028' },
|
|
|
|
|
- { repairId: '11', networkId: 'net014', repairDate: '2026-03-28', repairType: '4', repairContent: '滨江路西低压段PE管老化更换,原管道使用年限已到设计寿命,整体更换DN160 PE100新管', repairCompany: '沅陵燃气工程有限公司', repairCost: 78500, repairPerson: '赵明辉', createTime: '2026-03-28 07:30:00', remark: '更换长度约210m' },
|
|
|
|
|
- { repairId: '12', networkId: 'net004', repairDate: '2026-03-18', repairType: '6', repairContent: '古城北路中压段阀门井内积水导致阀门锈蚀,清理井室并更换锈蚀螺栓及附件', repairCompany: '怀化兴燃工程有限公司', repairCost: 3500, repairPerson: '王立新', createTime: '2026-03-18 13:25:10', remark: '' },
|
|
|
|
|
- { repairId: '13', networkId: 'net010', repairDate: '2026-03-10', repairType: '5', repairContent: '迎宾东路中压段直缝焊管焊缝补强,焊缝余高不符合规范,打磨处理后进行补焊', repairCompany: '湖南城市燃气技术公司', repairCost: 9800, repairPerson: '李志强', createTime: '2026-03-10 15:40:05', remark: '焊缝长度28mm' },
|
|
|
|
|
- { repairId: '14', networkId: 'net016', repairDate: '2026-02-25', repairType: '3', repairContent: '天宁西路低压段沿河侧管道外防腐保温层修复,河水浸泡导致保温层脱落约40m', repairCompany: '沅陵燃气工程有限公司', repairCost: 33500, repairPerson: '张建国', createTime: '2026-02-25 10:20:30', remark: '枯水期施工' },
|
|
|
|
|
- { repairId: '15', networkId: 'net007', repairDate: '2026-02-18', repairType: '2', repairContent: '古城南路中压段穿越路口管段套管更换,原钢套管腐蚀穿孔,换用加强级3PE防腐套管', repairCompany: '湖南省特种设备检测院', repairCost: 16500, repairPerson: '刘伟东', createTime: '2026-02-18 08:50:15', remark: '' },
|
|
|
|
|
- { repairId: '16', networkId: 'net017', repairDate: '2026-02-08', repairType: '4', repairContent: '天宁东路低压段凝水缸更换,冬季冻裂导致凝水缸壳体破损,更换为抗冻型凝水缸', repairCompany: '怀化兴燃工程有限公司', repairCost: 7200, repairPerson: '王立新', createTime: '2026-02-08 11:15:00', remark: '' },
|
|
|
|
|
- { repairId: '17', networkId: 'net013', repairDate: '2026-01-22', repairType: '1', repairContent: '建设东路中压段地基下沉导致管道变形,开挖后重新敷设管基并加装波纹补偿器', repairCompany: '沅陵燃气工程有限公司', repairCost: 25600, repairPerson: '赵明辉', createTime: '2026-01-22 16:35:48', remark: '沉降量约80mm' },
|
|
|
|
|
- { repairId: '18', networkId: 'net001', repairDate: '2026-01-10', repairType: '2', repairContent: '辰州北路高压段阴极保护系统维护,更换阳极地床,测试保护电位', repairCompany: '湖南省特种设备检测院', repairCost: 11200, repairPerson: '刘伟东', createTime: '2026-01-10 09:30:00', remark: '保护电位-1.15V~-1.22V' },
|
|
|
|
|
-])
|
|
|
|
|
|
|
+// ==================== 维修记录数据 ====================
|
|
|
|
|
+const tableData = ref([])
|
|
|
|
|
|
|
|
const pressureColors = { high: '#e63946', medium: '#f77f00', low: '#2a9d8f' }
|
|
const pressureColors = { high: '#e63946', medium: '#f77f00', low: '#2a9d8f' }
|
|
|
const repairedNetworkIds = computed(() => { const s = new Set(); tableData.value.forEach(r => s.add(r.networkId)); return s })
|
|
const repairedNetworkIds = computed(() => { const s = new Set(); tableData.value.forEach(r => s.add(r.networkId)); return s })
|
|
|
|
|
|
|
|
-function getPipelineName(id) { const p = pipelineData.find(p => p.id === id); return p ? p.name : id }
|
|
|
|
|
|
|
+async function loadNetworkOptions() {
|
|
|
|
|
+ if (networkOptions.value.length > 0) return
|
|
|
|
|
+ try { const res = await getPipeNetworkOptions(); networkOptions.value = res.data || [] } catch (e) { console.error(e) }
|
|
|
|
|
+}
|
|
|
|
|
+function getNetworkName(id) {
|
|
|
|
|
+ const found = networkOptions.value.find(n => n.networkId === id)
|
|
|
|
|
+ return found ? found.networkName : id
|
|
|
|
|
+}
|
|
|
|
|
+function getPipelineName(id) {
|
|
|
|
|
+ const name = getNetworkName(id)
|
|
|
|
|
+ return name !== id ? name : (pipelineData.find(p => p.id === id) || {}).name || id
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
-// ==================== 过滤分页 ====================
|
|
|
|
|
-const filteredData = computed(() => {
|
|
|
|
|
- let data = tableData.value
|
|
|
|
|
- if (searchForm.networkId) data = data.filter(r => r.networkId === searchForm.networkId)
|
|
|
|
|
- if (searchForm.repairType) data = data.filter(r => r.repairType === searchForm.repairType)
|
|
|
|
|
- return data.sort((a, b) => b.createTime.localeCompare(a.createTime))
|
|
|
|
|
-})
|
|
|
|
|
-const paginatedData = computed(() => filteredData.value.slice((pageNum.value - 1) * pageSize.value, pageNum.value * pageSize.value))
|
|
|
|
|
-const total = computed(() => filteredData.value.length)
|
|
|
|
|
|
|
+// ==================== 数据加载 ====================
|
|
|
|
|
+async function loadData() {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await getRepairRecordPage(pageNum.value, pageSize.value, searchForm)
|
|
|
|
|
+ tableData.value = (res.data && res.data.records) ? res.data.records : []
|
|
|
|
|
+ total.value = (res.data && res.data.total) ? res.data.total : 0
|
|
|
|
|
+ } catch (e) { console.error(e) } finally { loading.value = false }
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
// ==================== 百度地图 ====================
|
|
// ==================== 百度地图 ====================
|
|
|
function waitForBMapGL() {
|
|
function waitForBMapGL() {
|
|
@@ -288,7 +286,7 @@ function renderMapScene() {
|
|
|
const mid = { lng: convertCoord(rawMid.lng, rawMid.lat)[0], lat: convertCoord(rawMid.lng, rawMid.lat)[1] }
|
|
const mid = { lng: convertCoord(rawMid.lng, rawMid.lat)[0], lat: convertCoord(rawMid.lng, rawMid.lat)[1] }
|
|
|
const count = tableData.value.filter(r => r.networkId === pipe.id).length
|
|
const count = tableData.value.filter(r => r.networkId === pipe.id).length
|
|
|
const repairList = tableData.value.filter(r => r.networkId === pipe.id).slice(0, 3).map(r => `${r.repairDate} ${getDictLabel(repairTypeDict, r.repairType)}`).join('<br>')
|
|
const repairList = tableData.value.filter(r => r.networkId === pipe.id).slice(0, 3).map(r => `${r.repairDate} ${getDictLabel(repairTypeDict, r.repairType)}`).join('<br>')
|
|
|
- const html = `<div style="font-size:13px;max-width:300px;"><b>${pipe.id}</b> ${pipe.name}<br>
|
|
|
|
|
|
|
+ const html = `<div style="font-size:13px;max-width:300px;"><b>${pipe.name}</b>(${getNetworkName(pipe.id)})<br>
|
|
|
<span style="color:${pressureColors[pipe.pressure]};font-weight:bold;">${pipe.pressure === 'high' ? '高压' : pipe.pressure === 'medium' ? '中压' : '低压'}</span>
|
|
<span style="color:${pressureColors[pipe.pressure]};font-weight:bold;">${pipe.pressure === 'high' ? '高压' : pipe.pressure === 'medium' ? '中压' : '低压'}</span>
|
|
|
累计维修 <b style="color:#e63946;">${count}</b> 次
|
|
累计维修 <b style="color:#e63946;">${count}</b> 次
|
|
|
${count > 0 ? '<br><span style="color:#909399;font-size:11px;">' + repairList + '</span>' : ''}</div>`
|
|
${count > 0 ? '<br><span style="color:#909399;font-size:11px;">' + repairList + '</span>' : ''}</div>`
|
|
@@ -411,36 +409,28 @@ function initCharts() { try { initRiskPie() } catch (e) { console.warn('饼图
|
|
|
function resizeCharts() { riskPieChart?.resize(); repairTrendChart?.resize() }
|
|
function resizeCharts() { riskPieChart?.resize(); repairTrendChart?.resize() }
|
|
|
|
|
|
|
|
// ==================== 操作 ====================
|
|
// ==================== 操作 ====================
|
|
|
-function onFilterChange() { pageNum.value = 1 }
|
|
|
|
|
-function handleSearch() { pageNum.value = 1 }
|
|
|
|
|
|
|
+function onFilterChange() { pageNum.value = 1; loadData() }
|
|
|
|
|
+function handleSearch() { pageNum.value = 1; loadData() }
|
|
|
function handleReset() {
|
|
function handleReset() {
|
|
|
searchForm.networkId = ''; searchForm.repairType = ''; pageNum.value = 1
|
|
searchForm.networkId = ''; searchForm.repairType = ''; pageNum.value = 1
|
|
|
- nextTick(() => renderMapScene())
|
|
|
|
|
|
|
+ loadData()
|
|
|
}
|
|
}
|
|
|
function handleAdd() {
|
|
function handleAdd() {
|
|
|
dialogTitle.value = '新增'; dialogVisible.value = true
|
|
dialogTitle.value = '新增'; dialogVisible.value = true
|
|
|
Object.assign(formData, { repairId: '', networkId: '', repairDate: '', repairType: '', repairContent: '', repairCompany: '', repairCost: null, repairPerson: '', remark: '' })
|
|
Object.assign(formData, { repairId: '', networkId: '', repairDate: '', repairType: '', repairContent: '', repairCompany: '', repairCost: null, repairPerson: '', remark: '' })
|
|
|
|
|
+ loadNetworkOptions()
|
|
|
}
|
|
}
|
|
|
-function handleEdit(row) { dialogTitle.value = '编辑'; dialogVisible.value = true; Object.assign(formData, { ...row }) }
|
|
|
|
|
-function handleSubmit() {
|
|
|
|
|
- if (formData.repairId) {
|
|
|
|
|
- const idx = tableData.value.findIndex(r => r.repairId === formData.repairId)
|
|
|
|
|
- if (idx >= 0) tableData.value[idx] = { ...formData }
|
|
|
|
|
- ElMessage.success('修改成功')
|
|
|
|
|
- } else {
|
|
|
|
|
- formData.repairId = String(Date.now())
|
|
|
|
|
- formData.createTime = new Date().toLocaleString('zh-CN').replace(/\//g, '-')
|
|
|
|
|
- tableData.value.unshift({ ...formData })
|
|
|
|
|
- ElMessage.success('新增成功')
|
|
|
|
|
- }
|
|
|
|
|
- dialogVisible.value = false
|
|
|
|
|
- nextTick(() => { renderMapScene(); initCharts() })
|
|
|
|
|
|
|
+function handleEdit(row) { dialogTitle.value = '编辑'; dialogVisible.value = true; Object.assign(formData, { ...row }); loadNetworkOptions() }
|
|
|
|
|
+async function handleSubmit() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (formData.repairId) { await updateRepairRecord(formData); ElMessage.success('修改成功') }
|
|
|
|
|
+ else { await addRepairRecord(formData); ElMessage.success('新增成功') }
|
|
|
|
|
+ dialogVisible.value = false; loadData(); nextTick(() => renderMapScene())
|
|
|
|
|
+ } catch (e) { const msg = e?.response?.data?.msg || e?.message || '操作失败'; ElMessage.error(msg) }
|
|
|
}
|
|
}
|
|
|
function handleDelete(row) {
|
|
function handleDelete(row) {
|
|
|
- ElMessageBox.confirm('确认删除该维修记录?', '提示', { type: 'warning' }).then(() => {
|
|
|
|
|
- tableData.value = tableData.value.filter(r => r.repairId !== row.repairId)
|
|
|
|
|
- ElMessage.success('删除成功')
|
|
|
|
|
- nextTick(() => { renderMapScene(); initCharts() })
|
|
|
|
|
|
|
+ ElMessageBox.confirm('确认删除该维修记录?', '提示', { type: 'warning' }).then(async () => {
|
|
|
|
|
+ try { await deleteRepairRecord(row.repairId); ElMessage.success('删除成功'); loadData(); nextTick(() => renderMapScene()) } catch (e) { ElMessage.error('删除失败') }
|
|
|
}).catch(() => {})
|
|
}).catch(() => {})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -448,6 +438,8 @@ function handleDelete(row) {
|
|
|
let resizeTimer = null
|
|
let resizeTimer = null
|
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
|
await nextTick()
|
|
await nextTick()
|
|
|
|
|
+ await loadNetworkOptions()
|
|
|
|
|
+ await loadData()
|
|
|
waitForBMapGL()
|
|
waitForBMapGL()
|
|
|
initCharts()
|
|
initCharts()
|
|
|
window.addEventListener('resize', () => {
|
|
window.addEventListener('resize', () => {
|