|
|
@@ -3,10 +3,18 @@
|
|
|
<div class="page-heading">
|
|
|
<div class="page-title"><span class="page-title-icon"><el-icon><component :is="pageIcon" /></el-icon></span><div><h2>{{ title }}</h2><span class="muted">{{ view === 'gis' ? '设施分类图层、空间分布与详情联动' : '设施规模、状态与分类统计分析' }}</span></div></div>
|
|
|
<div class="heading-actions">
|
|
|
+ <template v-if="view === 'stats'">
|
|
|
+ <el-select v-model="statusFilter" clearable placeholder="全部状态" style="width: 130px" @change="loadData">
|
|
|
+ <el-option label="正常" value="0" /><el-option label="异常" value="1" />
|
|
|
+ </el-select>
|
|
|
+ <el-checkbox-group v-model="selectedTypes" @change="loadData">
|
|
|
+ <el-checkbox-button v-for="item in facilityTypes" :key="item.value" :value="item.value">{{ item.label }}</el-checkbox-button>
|
|
|
+ </el-checkbox-group>
|
|
|
+ </template>
|
|
|
<el-checkbox-group v-if="view === 'gis'" v-model="selectedTypes" @change="loadData">
|
|
|
<el-checkbox-button v-for="item in facilityTypes" :key="item.value" :value="item.value">{{ item.label }}</el-checkbox-button>
|
|
|
</el-checkbox-group>
|
|
|
- <el-button v-if="view === 'stats'" type="success" plain icon="Download" @click="exportData">导出</el-button>
|
|
|
+ <el-button v-if="view === 'stats'" type="success" plain icon="Download" :disabled="!selectedTypes.length" @click="exportData">导出</el-button>
|
|
|
<el-button :icon="Refresh" @click="loadData">刷新</el-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -37,7 +45,7 @@
|
|
|
<el-card shadow="never"><div class="card-title">设施数量与状态</div><div ref="barChartRef" class="chart"></div></el-card>
|
|
|
<el-card shadow="never"><div class="card-title">设施类型占比</div><div ref="pieChartRef" class="chart"></div></el-card>
|
|
|
</div>
|
|
|
- <el-card shadow="never"><el-table :data="rows" stripe border v-loading="loading"><el-table-column prop="name" label="统计项" min-width="180"/><el-table-column prop="value" label="数量" width="130"/><el-table-column prop="unit" label="单位" width="100"/><el-table-column prop="remark" label="说明" min-width="240"/></el-table><el-empty v-if="!rows.length" description="暂无统计数据"/></el-card>
|
|
|
+ <el-card shadow="never"><el-table :data="rows" stripe border v-loading="loading"><el-table-column prop="name" label="统计项" min-width="180"/><el-table-column prop="value" label="数量" width="130"/><el-table-column prop="unit" label="单位" width="100"/><el-table-column prop="remark" label="说明" min-width="240"/></el-table><el-empty v-if="!rows.length" :description="selectedTypes.length ? '暂无统计数据' : '请至少选择一类设施'"/></el-card>
|
|
|
</template>
|
|
|
|
|
|
<el-drawer v-model="detailVisible" class="detail-drawer" title="供水设施详情" direction="rtl" size="560px" append-to-body><el-descriptions :column="1" border><el-descriptions-item v-for="(value, key) in detail" :key="key" :label="key">{{ value ?? '-' }}</el-descriptions-item></el-descriptions></el-drawer>
|
|
|
@@ -51,6 +59,7 @@ import { DataAnalysis, Location, MapLocation, Refresh, Setting } from '@element-
|
|
|
import { saveAs } from 'file-saver'
|
|
|
import * as echarts from 'echarts'
|
|
|
import { exportPipeNetworkStatistics, getPipeNetworkDashboard, getWaterFacilityDetail, getWaterFacilityFeatures, getWaterFacilityOverview } from '@/api/pipeNetwork/waterSupply'
|
|
|
+import { buildPipeNetworkStatisticsQuery } from '@/utils/waterFacilityStatisticsModel'
|
|
|
import { normalizeMapPoints, unwrapResponse } from '@/utils/waterSupplyModel'
|
|
|
|
|
|
const props = defineProps({ title: { type: String, required: true }, view: { type: String, default: 'stats' } })
|
|
|
@@ -70,6 +79,7 @@ const mapPoints = ref([])
|
|
|
const mapLines = ref([])
|
|
|
const routeTypes = String(route.query.type || '').split(',').map(item => item.trim()).filter(Boolean)
|
|
|
const selectedTypes = ref(routeTypes.length ? facilityTypes.map(item => item.value).filter(item => routeTypes.includes(item)) : facilityTypes.map(item => item.value))
|
|
|
+const statusFilter = ref(String(route.query.status || ''))
|
|
|
const loading = ref(false)
|
|
|
const detailVisible = ref(false)
|
|
|
const detail = ref({})
|
|
|
@@ -89,6 +99,12 @@ const flattenMetrics = (section, value) => {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+const clearStatistics = async () => {
|
|
|
+ overview.value = []
|
|
|
+ rows.value = []
|
|
|
+ await renderCharts([])
|
|
|
+}
|
|
|
+
|
|
|
const renderCharts = async facilityOverview => {
|
|
|
await nextTick()
|
|
|
barChart?.dispose(); pieChart?.dispose()
|
|
|
@@ -124,7 +140,15 @@ const loadData = async () => {
|
|
|
overview.value = summary.filter(item => item.facilityType !== 'total').map(item => ({ label: item.facilityTypeName, value: item.geoCompleteCount ?? 0, unit: '个点位' }))
|
|
|
buildMap(unwrapResponse(featureResponse)?.features || [])
|
|
|
} else {
|
|
|
- const data = unwrapResponse(await getPipeNetworkDashboard()) || {}
|
|
|
+ if (!selectedTypes.value.length) {
|
|
|
+ await clearStatistics()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const params = buildPipeNetworkStatisticsQuery({
|
|
|
+ facilityTypes: selectedTypes.value,
|
|
|
+ status: statusFilter.value
|
|
|
+ })
|
|
|
+ const data = unwrapResponse(await getPipeNetworkDashboard(params)) || {}
|
|
|
const facilityOverview = Array.isArray(data.facilityOverview) ? data.facilityOverview : []
|
|
|
overview.value = facilityOverview.map(item => ({ label: item.facilityTypeName || item.facilityType, value: item.totalCount ?? 0, unit: '项' }))
|
|
|
rows.value = Object.entries(data).filter(([section]) => section !== 'facilityOverview').flatMap(([section, value]) => flattenMetrics(section, value)).map(item => ({ name: item.name || item.label || item.section || '统计项', value: item.value ?? item.totalCount ?? 0, unit: item.unit || '项', remark: item.remark || item.section || '' }))
|
|
|
@@ -133,8 +157,13 @@ const loadData = async () => {
|
|
|
} catch (error) { overview.value = []; rows.value = []; mapPoints.value = []; mapLines.value = []; console.warn(`[${props.title}] 数据加载失败`, error) } finally { loading.value = false }
|
|
|
}
|
|
|
const exportData = async () => {
|
|
|
+ if (props.view === 'stats' && !selectedTypes.value.length) return
|
|
|
try {
|
|
|
- const blob = await exportPipeNetworkStatistics()
|
|
|
+ const params = buildPipeNetworkStatisticsQuery({
|
|
|
+ facilityTypes: selectedTypes.value,
|
|
|
+ status: statusFilter.value
|
|
|
+ })
|
|
|
+ const blob = await exportPipeNetworkStatistics(params)
|
|
|
saveAs(new Blob([blob]), `管网数据统计分析_${new Date().toISOString().slice(0, 10)}.xlsx`)
|
|
|
} catch (error) {
|
|
|
console.warn('管网统计导出失败', error)
|