1032 lines
30 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<base-dialog
v-model:visible="props.visible"
title="影响点情况"
:table-data="tableData"
:table-columns="tableColumns"
:table-height="320"
:total="total"
:current-page="currentPage"
:page-size="pageSize"
showFilter="true"
:z-index="2000"
:max-width="1200"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
@close="handleClose"
>
<!-- 标题栏下方自定义插槽 -->
<template #header>
<!-- 统计卡片 -->
<div class="stats-cards">
<div
v-for="(item, index) in impactData"
:key="index"
@click="handleClick(index, item)"
class="stat-card"
:style="{
backgroundImage: `url(${cardType == index ? selectedIcon : unselectedIcon})`,
backgroundSize: '100% 100%',
backgroundPosition: 'center',
}"
>
<div class="stat-icon"><img :src="item.icon" alt="" /></div>
<div class="stat-content">
<span class="stat-label">{{ item.name }}</span>
<span class="stat-value">{{ item.count }}</span>
</div>
</div>
</div>
</template>
<!-- 筛选区域 -->
<template #filter>
<div class="filter-row">
<div class="filter-item">
<el-select
:teleported="false"
v-model="filterForm.pointLevel"
size="small"
placeholder="影响点等级"
class="filter-select"
clearable
@change="handleFilterChange"
>
<el-option v-for="option in pointLevelOptions" :key="option.value" :label="option.label" :value="option.value" />
</el-select>
</div>
<div class="filter-item">
<el-select
:teleported="false"
v-model="filterForm.region"
size="small"
placeholder="影响区域"
class="filter-select"
clearable
@change="handleFilterChange"
>
<el-option v-for="option in regionOptions" :key="option.value" :label="option.label" :value="option.value" />
</el-select>
</div>
<div class="filter-item">
<el-select
:teleported="false"
v-model="filterForm.roadType"
size="small"
placeholder="公路类型"
class="filter-select"
clearable
@change="handleFilterChange"
>
<el-option v-for="option in roadTypeOptions" :key="option.value" :label="option.label" :value="option.value" />
</el-select>
</div>
<div class="filter-item">
<el-button type="primary" class="search-btn" @click="handleSearch">查询</el-button>
</div>
</div>
</template>
<!-- 影响点等级列插槽 -->
<template #pointLevel="{ row }">
<span class="level-tag" :class="row.levelClass">{{ row.pointLevel }}</span>
</template>
<!-- 交通主管部门负责人列插槽 -->
<template #trafficDept="{ row }">
<div class="person-info">
<span class="person-name">{{ row.trafficDept.name }}</span>
<span class="person-phone">{{ row.trafficDept.phone }}</span>
</div>
</template>
<!-- 公路机构责任人列插槽 -->
<template #roadOrg="{ row }">
<div class="person-info">
<span class="person-name">{{ row.roadOrg.name }}</span>
<span class="person-phone">{{ row.roadOrg.phone }}</span>
</div>
</template>
<!-- 养护站负责人列插槽 -->
<template #maintenance="{ row }">
<div class="person-info">
<span class="person-name">{{ row.maintenance.name }}</span>
<span class="person-phone">{{ row.maintenance.phone }}</span>
</div>
</template>
<!-- 护路员列插槽 -->
<template #roadKeeper="{ row }">
<div class="person-info">
<span class="person-name">{{ row.roadKeeper.name }}</span>
<span class="person-phone">{{ row.roadKeeper.phone }}</span>
</div>
</template>
<!-- 一般人员路长履职列插槽 -->
<template #generalStaff="{ row }">
<div class="person-info">
<span class="person-name">{{ row.generalStaff.name }}</span>
<span class="person-phone">{{ row.generalStaff.phone }}</span>
</div>
</template>
<!-- 项目类型专用插槽 -->
<!-- 吹哨人列插槽 -->
<template #whistleblower="{ row }">
<div class="person-info">
<span class="person-name">{{ row.whistleblower?.name || '-' }}</span>
<span class="person-phone">{{ row.whistleblower?.phone || '-' }}</span>
</div>
</template>
<!-- 建设单位包保责任人列插槽 -->
<template #constructionUnit="{ row }">
<div class="person-info">
<span class="person-name">{{ row.constructionUnit?.name || '-' }}</span>
<span class="person-phone">{{ row.constructionUnit?.phone || '-' }}</span>
</div>
</template>
<!-- 施工单位包保责任人列插槽 -->
<template #constructionDept="{ row }">
<div class="person-info">
<span class="person-name">{{ row.constructionDept?.name || '-' }}</span>
<span class="person-phone">{{ row.constructionDept?.phone || '-' }}</span>
</div>
</template>
<!-- 驻地包保责任人列插槽 -->
<template #siteResponsible="{ row }">
<div class="person-info">
<span class="person-name">{{ row.siteResponsible?.name || '-' }}</span>
<span class="person-phone">{{ row.siteResponsible?.phone || '-' }}</span>
</div>
</template>
<!-- 区县级包保责任人列插槽 -->
<template #countyResponsible="{ row }">
<div class="person-info">
<span class="person-name">{{ row.countyResponsible?.name || '-' }}</span>
<span class="person-phone">{{ row.countyResponsible?.phone || '-' }}</span>
</div>
</template>
<!-- 市级包保责任人列插槽 -->
<template #cityResponsible="{ row }">
<div class="person-info">
<span class="person-name">{{ row.cityResponsible?.name || '-' }}</span>
<span class="person-phone">{{ row.cityResponsible?.phone || '-' }}</span>
</div>
</template>
<!-- 操作列插槽 -->
<template #operation="{ row }" fixed="right">
<span class="detail-link" @click="handleDetail(row)">详情</span>
</template>
</base-dialog>
</template>
<script setup>
import { ref, computed, watch, onMounted, nextTick } from 'vue'
import { Close, ArrowLeft, ArrowRight } from '@element-plus/icons-vue'
import { request } from '@/utils/request'
import { pointTypeOptions, pointLevelOptions, regionOptions, roadTypeOptions } from '../component/index.js'
import baseDialog from '../component/baseDialog.vue'
import respondedIcon from '../../../assets/xiangying/有回应@2x.png'
import notRespondedIcon from '../../../assets/xiangying/无回应@2x.png'
import selectedIcon from '../../../assets/xiangying/选中bg@2x.png'
import unselectedIcon from '../../../assets/xiangying/未选中bg@2x.png'
import Icon0 from '../../../assets/xiangying/选中@2x.png'
import Icon1 from '../../../assets/xiangying/未选中1@2x.png'
import Icon2 from '../../../assets/xiangying/未选中2@2x.png'
import Icon3 from '../../../assets/xiangying/未选中3@2x.png'
import Icon4 from '../../../assets/xiangying/未选中4@2x.png'
import { formatDateTime } from '../component/index.js'
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
handleImpactItem: {
type: Object,
default: () => {},
},
getdateRange: {
type: Array,
default: () => [],
},
})
const emit = defineEmits(['update:visible', 'close', 'detail', 'itemClick'])
// 筛选表单
const filterForm = ref({
pointType: '',
pointLevel: '',
region: '',
roadType: 'G,S',
})
// 统一的表格列配置(桥梁、边坡、隧道、路段使用)
const unifiedColumns = [
{ prop: 'id', label: '序号', width: '' },
{ prop: 'region', label: '影响区域', width: '' },
{ prop: 'pointType', label: '影响点类型', width: '' },
{ prop: 'pointLocation', label: '影响点位置', width: '' },
{ prop: 'pointLevel', label: '影响点等级', width: '', slot: 'pointLevel' },
{
prop: 'trafficDept',
label: '交通主管部门负责人',
width: '',
slot: 'trafficDept',
},
{ prop: 'roadOrg', label: '公路机构责任人', width: '', slot: 'roadOrg' },
{
prop: 'maintenance',
label: '养护站负责人',
width: '',
slot: 'maintenance',
},
{ prop: 'roadKeeper', label: '护路员', width: '', slot: 'roadKeeper' },
{
prop: 'generalStaff',
label: '一般人员(路长履职)',
width: '',
slot: 'generalStaff',
},
{
prop: 'operation',
label: '操作',
width: '80',
slot: 'operation',
fixed: 'right',
},
]
// 项目类型专用表格列配置
const projectColumns = [
{ prop: 'id', label: '序号', width: '60' },
{ prop: 'region', label: '影响区域', width: '' },
{ prop: 'pointType', label: '影响点类型', width: '' },
{ prop: 'siteName', label: '驻地名称', width: '' },
{
prop: 'whistleblower',
label: '吹哨人',
width: '',
slot: 'whistleblower',
},
{
prop: 'constructionUnit',
label: '建设单位包保责任人',
width: '',
slot: 'constructionUnit',
},
{
prop: 'constructionDept',
label: '施工单位包保责任人',
width: '',
slot: 'constructionDept',
},
{
prop: 'siteResponsible',
label: '驻地包保责任人',
width: '',
slot: 'siteResponsible',
},
{
prop: 'countyResponsible',
label: '区县级包保责任人',
width: '',
slot: 'countyResponsible',
},
{
prop: 'cityResponsible',
label: '市级包保责任人',
width: '',
slot: 'cityResponsible',
},
]
// 为兼容旧代码,保留变量名引用
const bridgeColumns = unifiedColumns
const slopeColumns = unifiedColumns
const tunnelColumns = unifiedColumns
const roadColumns = unifiedColumns
// 当前表格列配置
const tableColumns = ref(bridgeColumns)
// 表格数据
const tableData = ref([])
// 影响点数据
const impactData = ref([
{ name: '影响路段', count: 0, icon: Icon4, type: '路段' },
{ name: '影响桥梁', count: 0, icon: Icon0, type: '桥梁' },
{ name: '影响隧道', count: 0, icon: Icon2, type: '隧道' },
{ name: '影响边坡', count: 0, icon: Icon1, type: '边坡' },
{ name: '影响驻地', count: 0, icon: Icon3, type: '驻地' },
])
// 顶部卡片数据
const loadBarChartData = async () => {
console.log('原始时间范围:', props.handleImpactItem)
try {
const res = await request({
url: '/snow-ops-platform/weather-warning/affected-count',
method: 'GET',
params: {
start: formatDateTime(props.getdateRange[0]),
end: formatDateTime(props.getdateRange[1]),
warningId: props.handleImpactItem.warningId,
},
})
if (res.code == '00000') {
const data = res.data
if (data && Array.isArray(data)) {
// 英文转中文映射
const nameMap = {
'road-section': '路段',
bridge: '桥梁',
tunnel: '隧道',
slope: '边坡',
project: '驻地',
Road: '路段',
Bridge: '桥梁',
Tunnel: '隧道',
Slope: '边坡',
Project: '驻地',
}
// 转换英文name为中文
const convertedData = data.map((item) => {
if (item.extension == '项目') {
item.extension = '驻地'
}
const name = nameMap[item.name] || item.name
return { ...item, name }
})
convertedData.forEach((item) => {
impactData.value.forEach((stat) => {
if (stat.name.includes(item.extension)) {
stat.count = item.count || 0
}
})
})
}
}
} catch (error) {
console.error('加载柱状图数据失败:', error)
}
}
const cardType = ref('0')
const cardTypeVal = ref('路段')
// 根据 cardType 获取对应的表格列配置
const getColumnsByType = (type) => {
const typeMap = {
路段: bridgeColumns,
桥梁: slopeColumns,
隧道: tunnelColumns,
边坡: roadColumns,
驻地: projectColumns,
}
return typeMap[type] || bridgeColumns
}
// 根据 cardType 获取对应的 API 路径
const getApiUrlByType = (type) => {
const urlMap = {
桥梁: '/snow-ops-platform/weather-warning/affected-object/bridge',
边坡: '/snow-ops-platform/weather-warning/affected-object/slope',
隧道: '/snow-ops-platform/weather-warning/affected-object/tunnel',
驻地: '/snow-ops-platform/weather-warning/affected-object/project',
路段: '/snow-ops-platform/weather-warning/affected-object/road-section',
}
return urlMap[type] || '/snow-ops-platform/weather-warning/affected-object/bridge'
}
// 点击卡片切换
const handleClick = (index, item) => {
tableData.value = []
cardType.value = index + ''
cardTypeVal.value = item.type
// 切换表格列配置
tableColumns.value = getColumnsByType(item.type)
// 重置分页并获取数据
currentPage.value = 1
fetchData()
}
// 分页
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)
const totalPages = computed(() => Math.ceil(total.value / pageSize.value))
const visiblePages = computed(() => {
const pages = []
const maxVisible = 4
let start = Math.max(1, currentPage.value - Math.floor(maxVisible / 2))
let end = Math.min(totalPages.value, start + maxVisible - 1)
if (end - start + 1 < maxVisible) {
start = Math.max(1, end - maxVisible + 1)
}
for (let i = start; i <= end; i++) {
pages.push(i)
}
return pages
})
// 关闭对话框
const handleClose = () => {
emit('update:visible', false)
emit('close')
}
// 点击遮罩关闭已由base-dialog组件处理
// 查询
const handleSearch = () => {
console.log('查询条件:', filterForm.value)
currentPage.value = 1
fetchData()
}
// 查看详情
const handleDetail = (item) => {
emit('detail', { ...item, warningId: props.handleImpactItem.warningId })
emit('itemClick', { ...item, warningId: props.handleImpactItem.warningId })
}
// 分页操作
const handleSizeChange = (val) => {
pageSize.value = val
fetchData()
}
const handleCurrentChange = (val) => {
currentPage.value = val
fetchData()
}
// 筛选条件改变时触发
const handleFilterChange = () => {
currentPage.value = 1
fetchData()
}
// 获取时间参数
const getTimeParams = (type) => {
console.log('原始时间范围:', props.handleImpactItem)
let countyId = ''
console.log('区域:', filterForm.value)
regionOptions.value.forEach((item) => {
if (item.label === filterForm.value.region || item.value === filterForm.value.region) {
countyId = item.value || ''
}
})
let obj = {
start: formatDateTime(props.getdateRange[0] ? props.getdateRange[0] : props.handleImpactItem.dateRange?.[0] || ''),
end: formatDateTime(props.getdateRange[1] ? props.getdateRange[1] : props.handleImpactItem.dateRange?.[1] || ''),
limit: pageSize.value,
offset: (currentPage.value - 1) * pageSize.value,
countyId: countyId || '',
riskLevel: filterForm.value.pointLevel || '',
roadTypes: filterForm.value.roadType || '',
}
if (type === '路段' || type === '驻地') {
obj.warningId = props.handleImpactItem.warningId || ''
}
return obj
// {
// // start: `${year}-${month}-01 00:00:00`,
// // end: `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`,
// }
}
// 处理数据为统一格式
const processUnifiedData = (item, type) => {
// 获取等级样式类
const getLevelClass = (level) => {
const levelMap = {
红色预警: 'level-red',
橙色预警: 'level-orange',
黄色预警: 'level-yellow',
蓝色预警: 'level-blue',
高风险: 'level-red',
中风险: 'level-orange',
低风险: 'level-blue',
}
return levelMap[level] || ''
}
// 获取影响点等级
const pointLevel = item.riskLevel || item.warningLevel || item.level || item.GL1_PDDJ || item.GL1_JSDJ || '-'
// 基础数据
const baseData = {
item,
id: item.id,
// 影响区域
region: item.GL1_QXMC || item.COUNTY || item.county || item.region || item.ADMINISTRATIVE_REGION || item.COUNTY_NAME || '-',
// 影响点类型
pointType: impactData.value[type].type || '-',
// 影响点位置(根据类型取不同字段)
pointLocation: item.GL1_QLMC || item.NAME || item.GL1_SDMC || item.PROJECT_NAME || item.GL1_LXBH || item.name || '-',
// 影响点等级
pointLevel: pointLevel,
levelClass: getLevelClass(pointLevel),
// 交通主管部门负责人
trafficDept: {
// name: item.trafficDeptName || item.trafficManager || "-",
phone: item.trafficDeptPhone || item.trafficManagerPhone || '-',
name: '-',
phone: '-',
},
// 公路机构责任人
roadOrg: {
// name: item.roadOrgName || item.roadManager || "-",
// phone: item.roadOrgPhone || item.roadManagerPhone || "-",
name: '-',
phone: '-',
},
// 养护站负责人
maintenance: {
// name: item.maintenanceName || item.maintenanceManager || "-",
// phone: item.maintenancePhone || item.maintenanceManagerPhone || "-",
name: '-',
phone: '-',
},
// 护路员
roadKeeper: {
// name: item.roadKeeperName || item.roadKeeper || "-",
// phone: item.roadKeeperPhone || item.roadKeeperPhone || "-",
name: '-',
phone: '-',
},
// 一般人员(路长履职)
generalStaff: {
// name: item.generalStaffName || item.roadChief || "-",
// phone: item.generalStaffPhone || item.roadChiefPhone || "-",
name: '-',
phone: '-',
},
// 保留原始数据供详情使用
rawData: item,
}
// 桥梁类型特殊处理根据BASE_GLQL桥梁信息表字典
if (cardTypeVal.value === '桥梁') {
return {
...baseData,
// 影响区域 - 使用区县名称
region: item.GL1_QXMC || '-',
// 影响点位置 - 使用桥梁名称
pointLocation: item.GL1_QLMC || '-',
// 影响点等级 - 使用技术状况评级等级
pointLevel: item.GL1_JSZKPJDJ || item.GL1_PDDJ || item.GL1_CSFXDJ || '-',
levelClass: getLevelClass(item.GL1_JSZKPJDJ || item.GL1_PDDJ || item.GL1_CSFXDJ),
// // 交通主管部门负责人 - 管理单位负责人GL1_DWFZR
// trafficDept: {
// name: item.GL1_DWFZR || "-",
// phone: item.GL1_GLDWDH || "-",
// },
// // 公路机构责任人 - 统计负责人GL1_TJFZR
// roadOrg: {
// name: item.GL1_TJFZR || "-",
// phone: item.GL1_TJFZRDH || "-",
// },
// // 养护站负责人 - 养护单位责任人GL1_YHDWDH
// maintenance: {
// name: item.GL1_GLDWMC || "-",
// phone: item.GL1_YHDWDH || "-",
// },
// // 护路员 - 填报人
// roadKeeper: {
// name: item.GL1_TBRXM || "-",
// phone: item.GL1_TBRDH || "-",
// },
// // 一般人员(路长履职)- 桥梁工程师GL1_QLGCS
// generalStaff: {
// name: item.GL1_QLGCS || "-",
// phone: item.GL1_QLGCSDH || "-",
// },
}
}
// 隧道类型特殊处理根据BASE_GLSD隧道信息表字典
if (cardTypeVal.value === '隧道') {
return {
...baseData,
// 影响区域 - 使用区县名称
region: item.GL1_QXMC || item.GL1_QXBM || '-',
// 影响点位置 - 使用隧道名称
pointLocation: item.GL1_SDMC || '-',
// 影响点等级 - 使用评定等级
pointLevel: item.GL1_PDDJ || item.GL1_TJJGPDDJ || item.GL1_SDYHDJ || '-',
levelClass: getLevelClass(item.GL1_PDDJ || item.GL1_TJJGPDDJ || item.GL1_SDYHDJ),
// // 交通主管部门负责人 - 管养单位行政领导GL1_GYDWXZLD
// trafficDept: {
// name: item.GL1_GYDWXZLD || "-",
// phone: item.GL1_GYDWXZLDDH || "-",
// },
// // 公路机构责任人 - 隧道路政员GL1_SDLZY
// roadOrg: {
// name: item.GL1_SDLZY || "-",
// phone: item.GL1_SDLZYDH || "-",
// },
// // 养护站负责人 - 隧道养护工GL1_SDYHG
// maintenance: {
// name: item.GL1_SDYHG || "-",
// phone: item.GL1_SDYHGDH || "-",
// },
// // 护路员 - 隧道信息填报人GL1_SDXXTBR
// roadKeeper: {
// name: item.GL1_SDXXTBR || "-",
// phone: item.GL1_SDXXTBRDH || "-",
// },
// // 一般人员(路长履职)- 管养单位养护工程师GL1_GYDWYHGCS
// generalStaff: {
// name: item.GL1_GYDWYHGCS || "-",
// phone: item.GL1_GYDWYHGSCSDH || "-",
// },
}
}
// 路段类型特殊处理根据BASE_XJLD路线信息表字典
if (cardTypeVal.value === '路段') {
return {
...baseData,
// 影响区域 - 使用区县名称
region: item.COUNTY_NAME || '-',
// 影响点位置 - 使用路线名称+起终点桩号
pointLocation:
item.GL1_QDZH && item.GL1_ZDZH
? item.GL1_LXMC + '(k' + (item.GL1_QDZH + '').replace('.', '+') + '至k' + (item.GL1_ZDZH + '').replace('.', '+') + ')'
: item.GL1_LXMC,
// 影响点等级 - 使用风险等级
pointLevel: item.GL1_FXDJ || '',
levelClass: getLevelClass(item.GL1_FXDJ),
// 交通主管部门负责人 - 使用GL1_JTXM和GL1_JTDH
trafficDept: {
name: item.GL1_JTXM || '-',
phone: item.GL1_JTDH || '-',
},
// 公路机构责任人 - 使用GL1_JGXM和GL1_JGDH
roadOrg: {
name: item.GL1_JGXM || '-',
phone: item.GL1_JGDH || '-',
},
// 养护站负责人 - 使用GL1_YHXM和GL1_YHDH
maintenance: {
name: item.GL1_YHXM || '-',
phone: item.GL1_YHDH || '-',
},
// 护路员 - 使用GL1_HLXM和GL1_HLDH
roadKeeper: {
name: item.GL1_HLXM || item.ROAD_PATROL_WORKER_NAME || '-',
phone: item.GL1_HLDH || item.ROAD_PATROL_WORKER_PHONE || '-',
},
// 一般人员(路长履职)
generalStaff: {
name: item.ROAD_CAPTAIN_NAME || '-',
phone: item.ROAD_CAPTAIN_PHONE || '-',
},
}
}
// 项目类型特殊处理根据SQL字段映射
if (cardTypeVal.value === '驻地') {
return {
...baseData,
// 影响区域 - 使用COUNTY字段
region: item.COUNTY || item.county || item.county_name || '-',
// 影响点位置 - 使用项目名称
pointLocation: item.PROJECT_NAME || item.projectName || item.name || '-',
// 驻地名称
siteName: item.SITE_NAME || item.siteName || item.PROJECT_NAME || item.projectName || '-',
// 吹哨人 - WHISTLEBLOWER_NAME / WHISTLEBLOWER_PHONE
whistleblower: {
name: item.WHISTLEBLOWER_NAME || item.whistleblowerName || '-',
phone: item.WHISTLEBLOWER_PHONE || item.whistleblowerPhone || '-',
},
// 建设单位包保责任人 - OWNER_RESPONSIBLE_PERSON / OWNER_RESPONSIBLE_PHONE
constructionUnit: {
name: item.OWNER_RESPONSIBLE_PERSON || item.ownerResponsiblePerson || '-',
phone: item.OWNER_RESPONSIBLE_PHONE || item.ownerResponsiblePhone || '-',
},
// 施工单位包保责任人 - CONSTRUCTOR_RESPONSIBLE_PERSON / CONSTRUCTOR_RESPONSIBLE_PHONE
constructionDept: {
name: item.CONSTRUCTOR_RESPONSIBLE_PERSON || item.constructorResponsiblePerson || '-',
phone: item.CONSTRUCTOR_RESPONSIBLE_PHONE || item.constructorResponsiblePhone || '-',
},
// 驻地包保责任人 - SITE_RESPONSIBLE_PERSON / SITE_RESPONSIBLE_PHONE
siteResponsible: {
name: item.SITE_RESPONSIBLE_PERSON || item.siteResponsiblePerson || '-',
phone: item.SITE_RESPONSIBLE_PHONE || item.siteResponsiblePhone || '-',
},
// 区县级包保责任人 - DISTRICT_RESPONSIBLE_PERSON / DISTRICT_RESPONSIBLE_PHONE
countyResponsible: {
name: item.DISTRICT_RESPONSIBLE_PERSON || item.districtResponsiblePerson || '-',
phone: item.DISTRICT_RESPONSIBLE_PHONE || item.districtResponsiblePhone || '-',
},
// 市级包保责任人 - CITY_RESPONSIBLE_PERSON / CITY_RESPONSIBLE_PHONE
cityResponsible: {
name: item.CITY_RESPONSIBLE_PERSON || item.cityResponsiblePerson || '-',
phone: item.CITY_RESPONSIBLE_PHONE || item.cityResponsiblePhone || '-',
},
}
}
return baseData
}
// 根据类型处理数据(统一格式)
const processDataByType = (item, type) => {
return processUnifiedData(item, type)
}
// 获取数据
const fetchData = async () => {
console.log('获取第', currentPage.value, '页数据, 类型:', cardType.value)
try {
const timeParams = getTimeParams(cardTypeVal.value)
// 根据 cardType 获取对应的 API URL
const apiUrl = getApiUrlByType(cardTypeVal.value)
const res = await request({
url: apiUrl,
method: 'GET',
params: timeParams,
})
// 路段存在分页功能了,需要处理返回数据
if (cardTypeVal.value == '路段') {
if (res.data) {
tableData.value = res.data.map((item, index) => ({
...processDataByType(item, cardType.value),
id: index + 1,
}))
total.value = res.total || 0
}
} else if (cardTypeVal.value == '驻地') {
if (res.data) {
tableData.value = res.data.map((item, index) => ({
...processDataByType(item, cardType.value),
id: index + 1,
}))
total.value = res.total || 0
}
} else {
if (res.code === '00000' && res.data) {
// 处理返回数据
const allData = res.data
total.value = allData.length || 0
// 客户端分页:计算当前页的数据范围
const startIndex = (currentPage.value - 1) * pageSize.value
const endIndex = startIndex + pageSize.value
const currentPageData = allData.slice(startIndex, endIndex)
tableData.value = currentPageData.map((item, index) => ({
...processDataByType(item, cardType.value),
id: startIndex + index + 1,
}))
} else {
tableData.value = []
total.value = 0
}
}
} catch (error) {
console.error('获取影响点数据失败:', error)
tableData.value = []
total.value = 0
}
}
watch(
() => props.handleImpactItem,
(newVal) => {
total.value = 0
tableData.value = []
cardType.value = '0'
console.log('影响点情况=========newVal:', newVal)
if (newVal) {
filterForm.value.region = newVal.countyName
currentPage.value = 1
} else {
filterForm.value = {
district: '',
type: '',
roadConditionType: '',
roadType: '',
pointType: '',
}
cardType.value = '0'
}
fetchData()
loadBarChartData()
},
)
// 监听visible变化
watch(
() => props.visible,
(newVal) => {
tableColumns.value = bridgeColumns
// if (newVal) {
// filterForm.value = {
// pointType: '',
// pointLevel: '',
// region: '',
// }
// tableData.value = []
// cardType.value = '0'
// loadBarChartData()
// currentPage.value = 1
//
// }
},
)
</script>
<style lang="scss" scoped>
// 视频屏幕自适应 - 基于视口宽度动态调整
@function vw($px) {
@return calc($px / 1920 * 100vw);
}
// 统计卡片
.stats-cards {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: vw(16);
.stat-card {
width: 1200px;
text-align: center;
transition: all 0.3s;
cursor: pointer;
.stat-label {
font-size: vw(14);
color: rgba(255, 255, 255, 0.8);
font-weight: 500;
}
.stat-value {
font-size: vw(28);
font-weight: bold;
color: #40a9ff;
text-shadow: 0 0 10px rgba(64, 169, 255, 0.5);
}
}
}
// 筛选区域
.filter-section {
margin-bottom: vw(20);
.filter-row {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 12px;
}
.filter-item {
.filter-select {
width: vw(150);
:deep(.el-input__wrapper) {
background-color: rgba(30, 70, 120, 0.4);
border: 1px solid rgba(64, 169, 255, 0.3);
box-shadow: none;
border-radius: vw(4);
.el-input__inner {
color: #fff;
font-size: vw(13);
&::placeholder {
color: rgba(255, 255, 255, 0.5);
}
}
.el-input__suffix {
.el-icon {
color: rgba(255, 255, 255, 0.6);
}
}
}
}
.search-btn {
background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
border: none;
border-radius: vw(4);
padding: 0 vw(24);
height: vw(32);
font-size: vw(13);
&:hover {
background: linear-gradient(135deg, #69c0ff 0%, #40a9ff 100%);
}
}
}
}
.detail-link {
color: #40a9ff;
cursor: pointer;
font-size: vw(12);
&:hover {
color: #69c0ff;
text-decoration: underline;
}
}
// 下拉菜单样式
:deep(.el-select-dropdown) {
background-color: rgba(20, 50, 90, 0.98);
border: 1px solid rgba(64, 169, 255, 0.3);
.el-select-dropdown__item {
color: rgba(255, 255, 255, 0.85);
&:hover {
background-color: rgba(64, 169, 255, 0.2);
}
&.selected {
background-color: rgba(64, 169, 255, 0.3);
color: #40a9ff;
}
}
}
// 统计卡片
.stats-cards {
display: flex;
gap: 12px;
.stat-card {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
transition: all 0.3s;
cursor: pointer;
flex: 1;
&:hover {
background: rgba(30, 70, 120, 0.9);
border-color: rgba(64, 169, 255, 0.6);
box-shadow: 0 0 15px rgba(64, 169, 255, 0.3);
}
.stat-icon {
font-size: 18px;
color: #40a9ff;
width: 34px;
height: 34px;
display: flex;
align-items: center;
justify-content: center;
img {
width: 100%;
height: 100%;
}
}
.stat-content {
display: flex;
align-items: center;
gap: 6px;
.stat-label {
font-size: 14px;
color: #fff;
font-weight: 500;
}
.stat-value {
font-size: 14px;
font-weight: bold;
color: #40a9ff;
}
}
}
}
</style>