784 lines
25 KiB
Vue
Raw Normal View History

2026-04-13 14:04:56 +08:00
<template>
2026-05-09 15:25:44 +08:00
<div class="detail-container">
<el-card class="basic-card">
<template #header>
<div class="card-header">
<span>基本信息</span>
</div>
</template>
<el-descriptions column="3">
<el-descriptions-item label="预警标题">{{ detailData.headline || '-' }}</el-descriptions-item>
<el-descriptions-item label="预警类型">{{ detailData.weatherWarningType || '-' }}</el-descriptions-item>
<el-descriptions-item label="发送时间">{{ detailData.createTime || '-' }}</el-descriptions-item>
<el-descriptions-item label="生效时间">{{ detailData.onset || '-' }}</el-descriptions-item>
<el-descriptions-item label="接收时间">{{ detailData.receiveTime || '-' }}</el-descriptions-item>
<el-descriptions-item label="预警转发时间">{{ detailData.forwardTime || '-' }}</el-descriptions-item>
<el-descriptions-item span="3" label="预警结束时间">{{ detailData.expires || '-' }}</el-descriptions-item>
<el-descriptions-item span="3" label="预警描述">{{ detailData.description || '-' }}</el-descriptions-item>
<el-descriptions-item span="3" label="响应措施">{{}}</el-descriptions-item>
</el-descriptions>
</el-card>
<el-card class="sites-card">
<template #header>
<div class="card-header">
<span>影响情况</span>
</div>
</template>
<div class="table">
<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>
<div class="search-form">
<el-select
class="search-item"
:teleported="false"
v-model="filterForm.pointLevel"
size="small"
placeholder="影响点等级"
clearable
@change="handleFilterChange"
>
<el-option v-for="option in pointLevelOptions" :key="option.value" :label="option.label" :value="option.value" />
</el-select>
<el-select
:teleported="false"
v-model="filterForm.region"
size="small"
placeholder="影响区域"
class="search-item"
clearable
@change="handleFilterChange"
placement="bottom-start"
>
<el-option v-for="option in regionOptions" :key="option.value" :label="option.label" :value="option.value" />
</el-select>
<el-select
:teleported="false"
v-model="filterForm.roadType"
size="small"
placeholder="公路类型"
class="search-item"
clearable
@change="handleFilterChange"
>
<el-option v-for="option in roadTypeOptions" :key="option.value" :label="option.label" :value="option.value" />
</el-select>
</div>
<DynamicTable :dataSource="tableData" :columns="columns" :autoHeight="true" :pagination="pagination"></DynamicTable>
</div>
</el-card>
</div>
2026-04-13 14:04:56 +08:00
</template>
<script setup>
2026-05-09 15:25:44 +08:00
import { ref, onMounted, watch, computed, h, reactive } from 'vue'
import { request } from '@/utils/request'
import DynamicTable from '../../../component/DynamicTable/index.js'
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'
2026-04-13 14:04:56 +08:00
const props = defineProps({
2026-05-09 15:25:44 +08:00
row: {
type: Object,
default: {},
},
})
2026-04-13 14:04:56 +08:00
const detailData = ref({})
2026-05-09 15:25:44 +08:00
const tableData = ref([])
const cardType = ref('0')
const cardTypeVal = ref('路段')
const filterForm = reactive({})
// 格式化时间函数
const formatDateTime = (dateStr) => {
if (!dateStr) return '-'
const date = new Date(dateStr)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
const hours = String(date.getHours()).padStart(2, '0')
const minutes = String(date.getMinutes()).padStart(2, '0')
const seconds = String(date.getSeconds()).padStart(2, '0')
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}
// 分页
const pagination = reactive({
current: 1,
pageSize: 10,
total: 0,
pageSizes: [10, 20, 50],
layout: 'prev, pager, next, jumper',
onChange: (page, pageSize) => {
pagination.current = page
pagination.pageSize = pageSize
getAffectedSites()
},
})
2026-04-13 14:04:56 +08:00
// 根据预警ID获取预警详情
const getDetailData = async (id) => {
2026-05-09 15:25:44 +08:00
try {
const res = await request({
url: '/snow-ops-platform/weatherWarning/getById',
method: 'GET',
params: {
id: id,
},
})
if (res.code === '00000') {
detailData.value = res.data
} else {
throw new Error(res.message)
2026-04-13 14:04:56 +08:00
}
2026-05-09 15:25:44 +08:00
} catch (error) {
ElMessage.error(error.message)
console.log(error)
}
2026-04-13 14:04:56 +08:00
}
2026-05-09 15:25:44 +08:00
// 根据 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'
2026-04-13 14:04:56 +08:00
}
2026-05-09 15:25:44 +08:00
// 根据类型处理数据(统一格式)
const processDataByType = (item, type) => {
return processUnifiedData(item, type)
}
// 处理数据为统一格式
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: '-',
2026-04-13 14:04:56 +08:00
},
2026-05-09 15:25:44 +08:00
// 公路机构责任人
roadOrg: {
// name: item.roadOrgName || item.roadManager || "-",
// phone: item.roadOrgPhone || item.roadManagerPhone || "-",
name: '-',
phone: '-',
2026-04-13 14:04:56 +08:00
},
2026-05-09 15:25:44 +08:00
// 养护站负责人
maintenance: {
// name: item.maintenanceName || item.maintenanceManager || "-",
// phone: item.maintenancePhone || item.maintenanceManagerPhone || "-",
name: '-',
phone: '-',
2026-04-13 14:04:56 +08:00
},
2026-05-09 15:25:44 +08:00
// 护路员
roadKeeper: {
// name: item.roadKeeperName || item.roadKeeper || "-",
// phone: item.roadKeeperPhone || item.roadKeeperPhone || "-",
name: '-',
phone: '-',
2026-04-13 14:04:56 +08:00
},
2026-05-09 15:25:44 +08:00
// 一般人员(路长履职)
generalStaff: {
// name: item.generalStaffName || item.roadChief || "-",
// phone: item.generalStaffPhone || item.roadChiefPhone || "-",
name: '-',
phone: '-',
2026-04-13 14:04:56 +08:00
},
2026-05-09 15:25:44 +08:00
// 保留原始数据供详情使用
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 || "-",
// },
}
}
2026-04-13 14:04:56 +08:00
2026-05-09 15:25:44 +08:00
// 路段类型特殊处理根据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
}
// 根据区县ID、预警生效时间和预警结束时间 查询受影响的驻地列表
const getAffectedSites = async () => {
try {
const res = await request({
url: getApiUrlByType(cardTypeVal.value),
method: 'GET',
params: {
start: formatDateTime(props.row.onset),
end: formatDateTime(props.row.expires),
limit: pagination.pageSize,
offset: (pagination.current - 1) * pagination.pageSize,
countyId: props.row.areaCode,
...filterForm,
},
})
// 路段存在分页功能了,需要处理返回数据
if (cardTypeVal.value == '路段') {
if (res.data) {
tableData.value = res.data.map((item, index) => ({
...processDataByType(item, cardType.value),
id: index + 1,
}))
pagination.total = res.total || 0
}
} else if (cardTypeVal.value == '驻地') {
if (res.data) {
tableData.value = res.data.map((item, index) => ({
...processDataByType(item, cardType.value),
id: index + 1,
}))
pagination.total = res.total || 0
}
2026-05-09 15:31:06 +08:00
} else if (cardTypeVal.value == '桥梁') {
if (res.data) {
tableData.value = res.data.map((item, index) => ({
...processDataByType(item, cardType.value),
id: index + 1,
}))
pagination.total = res.total || 0
}
2026-05-09 15:25:44 +08:00
} else {
if (res.code === '00000' && res.data) {
// 处理返回数据
const allData = res.data
pagination.total = 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 = []
pagination.total = 0
}
}
} catch (error) {
console.error('获取影响点数据失败:', error)
tableData.value = []
pagination.total = 0
}
}
// 影响点等级选项
const pointLevelOptions = [
{ label: '全部', value: '' },
{ label: '低风险', value: '低风险' },
{ label: '中风险', value: '中风险' },
{ label: '较高风险', value: '较高风险' },
{ label: '高风险', value: '高风险' },
2026-04-13 14:04:56 +08:00
]
2026-05-09 15:25:44 +08:00
// 影响区域选项
const regionOptions = ref([])
const fetchDistrictOptions = async () => {
try {
const res = await request({
url: '/snow-ops-platform/sm-event/dashboard/district-options',
method: 'GET',
})
if (res && res.code === '00000' && Array.isArray(res.data)) {
// 将接口返回的数据转换为选项格式
const options = res.data.map((item) => ({
label: item.qxmc,
value: item.xzdm,
}))
// 保留"全部"选项,并添加接口返回的数据
regionOptions.value = [{ label: '全部', value: '' }, ...options]
return options
}
} catch (error) {
console.error('获取影响区域选项失败:', error)
}
return regionOptions.value
}
// 公路类型选项
const roadTypeOptions = ref([
{ label: '全部', value: '' },
{ label: '国省道', value: 'G,S' },
{ label: '农村公路', value: ' X, Y, C' },
])
// 筛选条件改变时触发
const handleFilterChange = () => {
pagination.current = 1
getAffectedSites()
}
// 影响点数据
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 () => {
try {
const res = await request({
url: '/snow-ops-platform/weather-warning/affected-count',
method: 'GET',
params: {
start: formatDateTime(props.row.onset),
end: formatDateTime(props.row.expires),
},
})
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)
}
}
2026-04-13 14:04:56 +08:00
2026-05-09 15:25:44 +08:00
// 点击卡片切换
const handleClick = (index, item) => {
tableData.value = []
cardType.value = index + ''
cardTypeVal.value = item.type
2026-04-13 14:04:56 +08:00
2026-05-09 15:25:44 +08:00
columns.value = getColumnsByType(item.type)
pagination.current = 1
getAffectedSites()
}
// 统一的表格列配置(桥梁、边坡、隧道、路段使用)
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 columns = ref(unifiedColumns)
// 根据 cardType 获取对应的表格列配置
const getColumnsByType = (type) => {
const typeMap = {
路段: unifiedColumns,
桥梁: unifiedColumns,
隧道: unifiedColumns,
边坡: unifiedColumns,
驻地: projectColumns,
}
return typeMap[type] || unifiedColumns
}
onMounted(async () => {
await loadBarChartData()
await fetchDistrictOptions()
await getDetailData(props.row.id)
await getAffectedSites()
})
2026-04-13 14:04:56 +08:00
</script>
2026-05-09 15:25:44 +08:00
<style scoped lang="scss">
2026-04-13 14:04:56 +08:00
.detail-container {
2026-05-09 15:25:44 +08:00
display: flex;
flex-direction: column;
gap: 20px;
}
.table {
display: flex;
flex-direction: column;
gap: 10px;
}
// 统计卡片
.stats-cards {
display: flex;
gap: 12px;
background-color: #16334e;
padding: 5px;
.stat-card {
2026-04-13 14:04:56 +08:00
display: flex;
2026-05-09 15:25:44 +08:00
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;
}
}
}
}
.search-form {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
gap: 12px;
.search-item {
width: 150px;
}
2026-04-13 14:04:56 +08:00
}
2026-05-09 15:25:44 +08:00
</style>