添加出库水温监测数据
This commit is contained in:
parent
ed29837df1
commit
68e7dc11be
@ -62,14 +62,22 @@ export function getMonitorData(data: any) {
|
||||
data
|
||||
});
|
||||
}
|
||||
// 生态流量 -限制范围查询
|
||||
export function getEngLimit(data: any) {
|
||||
// 监测数据 - 水温
|
||||
export function getMonitorDataWaterTemp(data: any) {
|
||||
return request({
|
||||
url: '/eq/data/getEngLimit',
|
||||
url: '/api/wmp-env-server/sw/alongDetail/qgc/GetKendoListCust',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
// 监测数据 - 水温 - 查询显示 综合/等温
|
||||
export function getMonitorDataWaterTempPowerStation(params: any) {
|
||||
return request({
|
||||
url: '/api/wmp-env-server/sw/wtrv/getIoWtrvFlag',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
// 生态流量 - 限制范围查询 - 日
|
||||
export function getEngLimitDay(data: any) {
|
||||
return request({
|
||||
@ -78,3 +86,11 @@ export function getEngLimitDay(data: any) {
|
||||
data
|
||||
});
|
||||
}
|
||||
// 生态流量 - 限制范围查询 - 月
|
||||
export function getEngLimit(data: any) {
|
||||
return request({
|
||||
url: '/eq/interval/qgc/month/GetKendoListCust',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
@ -11,6 +11,10 @@
|
||||
:row-key="rowKey"
|
||||
@change="handleTableChange"
|
||||
>
|
||||
<!-- 合计行插槽 -->
|
||||
<template #summary>
|
||||
<slot name="summary"></slot>
|
||||
</template>
|
||||
<!-- 使用 bodyCell 插槽透传自定义列内容 -->
|
||||
<template #bodyCell="{ column, text, record, index }">
|
||||
<template v-for="slotName in customSlotNames" :key="slotName">
|
||||
|
||||
@ -152,7 +152,7 @@ const columnsConfig = ref([
|
||||
columns: BasicColumns
|
||||
},
|
||||
{
|
||||
type: 'wt_point',
|
||||
type: 'WT',
|
||||
columns: wtPointColumns
|
||||
},
|
||||
{
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="monitor-info">
|
||||
<!-- Tabs 区域 -->
|
||||
<a-tabs v-model:activeKey="activeTabKey">
|
||||
<a-tabs v-model:activeKey="activeTabKey" @change="handleTabChange">
|
||||
<a-tab-pane v-for="tab in tabsList" :key="tab.key" :tab="tab.name" />
|
||||
<template #rightExtra>
|
||||
<div class="search-bar">
|
||||
@ -17,40 +17,105 @@
|
||||
<a-button type="primary" class="search-btn" @click="handleSearch">
|
||||
查询
|
||||
</a-button>
|
||||
<a-button
|
||||
v-if="activeTabKey === 'swjc.tabs.jcsj'"
|
||||
type="primary"
|
||||
class="search-btn"
|
||||
@click="handleExport"
|
||||
>
|
||||
导出
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</a-tabs>
|
||||
<div class="tab-checkbox" v-if="activeTabKey === 'swjc.tabs.jcsj'">
|
||||
<a-checkbox-group
|
||||
v-model:value="selectedColumns"
|
||||
name="checkboxgroup"
|
||||
:options="filteredCheckBoxOptions"
|
||||
class="checkbox-group"
|
||||
@change="handleCheckboxChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<div v-if="activeTabKey === 'dzxq.tabs.jcsj'" class="tab-content">
|
||||
<a-spin :spinning="isLoading" tip="加载中...">
|
||||
<!-- 左侧图表 + 右侧表格 -->
|
||||
<div v-if="activeTabKey" class="tab-content">
|
||||
<div class="content-body">
|
||||
<div class="chart-wrapper" ref="chartRef"></div>
|
||||
<!-- 电站运行过程线 -->
|
||||
<PowerStationChart
|
||||
v-if="activeTabKey === 'dzxq.tabs.jcsj'"
|
||||
:data="chartData"
|
||||
/>
|
||||
<!-- 水温 -->
|
||||
<WaterTempChart
|
||||
v-if="activeTabKey === 'swjc.tabs.jcsj'"
|
||||
:data="chartData"
|
||||
:mode="currentChartMode"
|
||||
/>
|
||||
<!-- 右侧表格 -->
|
||||
<div class="table-wrapper">
|
||||
<BasicTable
|
||||
ref="tableRef"
|
||||
:scrollY="480"
|
||||
:scrollX="980"
|
||||
:scrollY="activeTabKey === 'swjc.tabs.jcsj' ? 360 : 480"
|
||||
:scrollX="tableScrollX"
|
||||
:columns="currentColumns"
|
||||
:data="tableData"
|
||||
:isPage="true"
|
||||
/>
|
||||
>
|
||||
<template #summary>
|
||||
<a-table-summary fixed v-if="activeTabKey === 'swjc.tabs.jcsj'">
|
||||
<template
|
||||
v-for="summaryRow in summaryRows"
|
||||
:key="summaryRow.label"
|
||||
>
|
||||
<a-table-summary-row class="summary-row">
|
||||
<a-table-summary-cell :index="0">
|
||||
{{ summaryRow.label }}
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell
|
||||
v-for="col in summaryColumns"
|
||||
:key="col.dataIndex"
|
||||
:index="col.summaryIndex"
|
||||
>
|
||||
{{ summaryRow.cells[col.dataIndex]?.value ?? '-' }}
|
||||
<Tooltip
|
||||
v-if="summaryRow.cells[col.dataIndex]?.time"
|
||||
:title="`时间:${
|
||||
summaryRow.cells[col.dataIndex].time
|
||||
}`"
|
||||
placement="top"
|
||||
>
|
||||
<InfoCircleOutlined class="summary-tip-icon" />
|
||||
</Tooltip>
|
||||
</a-table-summary-cell>
|
||||
</a-table-summary-row>
|
||||
</template>
|
||||
</a-table-summary>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-spin>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch, computed, onMounted, onUnmounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { ref, watch, computed, onMounted } from 'vue';
|
||||
import dayjs, { Dayjs } from 'dayjs';
|
||||
import { getMonitorData } from '@/api/mapModal';
|
||||
import { Tooltip } from 'ant-design-vue';
|
||||
import {
|
||||
getMonitorData,
|
||||
getMonitorDataWaterTemp,
|
||||
getMonitorDataWaterTempPowerStation
|
||||
} from '@/api/mapModal';
|
||||
import { useModelStore } from '@/store/modules/model';
|
||||
import BasicTable from '@/components/BasicTable/index.vue';
|
||||
import { DateSetting } from '@/utils/enumeration';
|
||||
import { InfoCircleOutlined } from '@ant-design/icons-vue';
|
||||
import PowerStationChart from './charts/PowerStationChart.vue';
|
||||
import WaterTempChart from './charts/WaterTempChart.vue';
|
||||
import { useWaterTempTable } from './composables/useWaterTempTable';
|
||||
|
||||
const modelStore = useModelStore();
|
||||
|
||||
@ -67,34 +132,77 @@ const props = defineProps({
|
||||
|
||||
const hasLoaded = ref(false);
|
||||
const isLoading = ref(false);
|
||||
const activeTabKey = ref('dzxq.tabs.jcsj');
|
||||
const chartRef = ref<HTMLDivElement | null>(null);
|
||||
let chartInstance: echarts.ECharts | null = null;
|
||||
const tableRef = ref<any>(null);
|
||||
const tableData = ref<any[]>([]);
|
||||
const chartData = ref<any[]>([]);
|
||||
|
||||
// ==================== Tab 配置 ====================
|
||||
const tabsConfig: Record<string, any[]> = {
|
||||
'dzxq.tabs.jcsj': [{ name: '电站运行过程线', key: 'dzxq.tabs.jcsj' }]
|
||||
'dzxq.tabs.jcsj': [{ name: '电站运行过程线', key: 'dzxq.tabs.jcsj' }],
|
||||
'swjc.tabs.jcsj': [{ name: '水温', key: 'swjc.tabs.jcsj' }]
|
||||
};
|
||||
|
||||
const tabsList = computed(() => {
|
||||
return tabsConfig[props.code] || tabsConfig['dzxq.tabs.jcsj'];
|
||||
});
|
||||
|
||||
// 默认 activeTabKey 根据 code 动态设置
|
||||
const getDefaultTabKey = () => {
|
||||
const tabs = tabsConfig[props.code];
|
||||
return tabs && tabs.length > 0 ? tabs[0].key : 'dzxq.tabs.jcsj';
|
||||
};
|
||||
const activeTabKey = ref(getDefaultTabKey());
|
||||
|
||||
// ==================== 水温表格逻辑(组合式函数) ====================
|
||||
const {
|
||||
selectedColumns,
|
||||
showSummaryCheckbox,
|
||||
showDeepCheckbox,
|
||||
filteredCheckBoxOptions,
|
||||
currentChartMode,
|
||||
currentColumns,
|
||||
tableScrollX,
|
||||
summaryColumns,
|
||||
summaryRows,
|
||||
handleCheckboxChange: handleCheckboxChangeBase
|
||||
} = useWaterTempTable(chartData, activeTabKey);
|
||||
|
||||
const handleCheckboxChange = (values: any[]) => {
|
||||
handleCheckboxChangeBase(values, fetchData);
|
||||
};
|
||||
|
||||
// ==================== 时间选择器配置 ====================
|
||||
const defaultDateRangeConfig: Record<string, { days: number }> = {
|
||||
'dzxq.tabs.jcsj': { days: 30 },
|
||||
'swjc.tabs.jcsj': { days: 7 }
|
||||
};
|
||||
|
||||
const initDateRange = (): [Dayjs, Dayjs] => {
|
||||
const days = defaultDateRangeConfig[activeTabKey.value]?.days || 30;
|
||||
const endDate = dayjs();
|
||||
let startDate = dayjs().subtract(days, 'day');
|
||||
|
||||
if (activeTabKey.value === 'swjc.tabs.jcsj') {
|
||||
startDate = startDate.startOf('day');
|
||||
}
|
||||
|
||||
return [startDate, endDate];
|
||||
};
|
||||
|
||||
const dateRange = ref<[Dayjs, Dayjs] | undefined>(initDateRange());
|
||||
|
||||
const timeConfig: Record<string, { showTime: boolean; format: string }> = {
|
||||
'dzxq.tabs.jcsj': { showTime: true, format: 'YYYY-MM-DD HH:mm' }
|
||||
'dzxq.tabs.jcsj': { showTime: true, format: 'YYYY-MM-DD HH:mm' },
|
||||
'swjc.tabs.jcsj': { showTime: true, format: 'YYYY-MM-DD HH:mm' }
|
||||
};
|
||||
|
||||
const currentTimeConfig = computed(() => {
|
||||
return timeConfig[props.code] || timeConfig['dzxq.tabs.jcsj'];
|
||||
return timeConfig[activeTabKey.value] || timeConfig['dzxq.tabs.jcsj'];
|
||||
});
|
||||
|
||||
const showTime = computed(() => currentTimeConfig.value.showTime);
|
||||
const dateFormat = computed(() => currentTimeConfig.value.format);
|
||||
|
||||
// 时分秒配置(不选秒)
|
||||
const showTimeConfig = {
|
||||
format: 'HH:mm',
|
||||
hourStep: 1,
|
||||
@ -102,103 +210,19 @@ const showTimeConfig = {
|
||||
secondStep: 60
|
||||
};
|
||||
|
||||
// 初始化日期范围:当前日期到前一个月
|
||||
const initDateRange = (): [Dayjs, Dayjs] => {
|
||||
const endDate = dayjs();
|
||||
const startDate = dayjs().subtract(1, 'month');
|
||||
return [startDate, endDate];
|
||||
};
|
||||
|
||||
const dateRange = ref<[Dayjs, Dayjs] | undefined>(initDateRange());
|
||||
|
||||
// 禁用超过当前日期的选项
|
||||
const disabledDate = (current: Dayjs) => {
|
||||
return current && current.isAfter(dayjs(), 'day');
|
||||
};
|
||||
|
||||
// ==================== 表格配置 ====================
|
||||
const tableColumnsConfig: Record<string, any[]> = {
|
||||
'dzxq.tabs.jcsj': [
|
||||
{
|
||||
title: '时间',
|
||||
dataIndex: 'tm',
|
||||
width: 180,
|
||||
fixed: 'left',
|
||||
customRender: ({ text }: any) =>
|
||||
text ? dayjs(text).format('YYYY-MM-DD HH:mm:ss') : '-'
|
||||
},
|
||||
{
|
||||
title: '坝上水位(m)',
|
||||
dataIndex: 'rz',
|
||||
width: 130,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text).toFixed(2) : '-'
|
||||
},
|
||||
{
|
||||
title: '坝下水位(m)',
|
||||
dataIndex: 'dz',
|
||||
width: 130,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text).toFixed(2) : '-'
|
||||
},
|
||||
{
|
||||
title: '入库流量(m³/s)',
|
||||
dataIndex: 'qi',
|
||||
width: 130,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Math.round(Number(text)) : '-'
|
||||
},
|
||||
{
|
||||
title: '出库流量(m³/s)',
|
||||
dataIndex: 'qo',
|
||||
width: 130,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text) : '-'
|
||||
},
|
||||
{
|
||||
title: '生态流量(m³/s)',
|
||||
dataIndex: 'qec',
|
||||
width: 130,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text).toFixed(1) : '-'
|
||||
},
|
||||
{
|
||||
title: '生态流量限值(m³/s)',
|
||||
dataIndex: 'qecLimit',
|
||||
width: 150,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text).toFixed(1) : '-'
|
||||
}
|
||||
]
|
||||
// ==================== API 配置 ====================
|
||||
const apiConfig: Record<string, Function> = {
|
||||
'dzxq.tabs.jcsj': getMonitorData,
|
||||
'swjc.tabs.jcsj': getMonitorDataWaterTemp
|
||||
};
|
||||
|
||||
const currentColumns = computed(() => {
|
||||
return tableColumnsConfig[props.code] || tableColumnsConfig['dzxq.tabs.jcsj'];
|
||||
});
|
||||
|
||||
// ==================== 图表图例配置 ====================
|
||||
const chartLegendConfig: Record<string, string[]> = {
|
||||
'dzxq.tabs.jcsj': [
|
||||
'坝上水位',
|
||||
'坝下水位',
|
||||
'入库流量',
|
||||
'出库流量',
|
||||
'生态流量',
|
||||
'生态流量限值'
|
||||
]
|
||||
};
|
||||
|
||||
const chartLegendData = computed(() => {
|
||||
return chartLegendConfig[props.code] || chartLegendConfig['dzxq.tabs.jcsj'];
|
||||
});
|
||||
|
||||
// ==================== 数据请求 ====================
|
||||
const fetchData = async () => {
|
||||
if (!dateRange.value) return;
|
||||
|
||||
isLoading.value = true;
|
||||
|
||||
const params = {
|
||||
// 构建 filter 参数
|
||||
const buildFilterParams = () => {
|
||||
return {
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
@ -212,13 +236,13 @@ const fetchData = async () => {
|
||||
field: 'tm',
|
||||
operator: 'gte',
|
||||
dataType: 'date',
|
||||
value: dateRange.value[0].format('YYYY-MM-DD HH:mm:ss')
|
||||
value: dateRange.value![0].format('YYYY-MM-DD HH:mm:ss')
|
||||
},
|
||||
{
|
||||
field: 'tm',
|
||||
operator: 'lte',
|
||||
dataType: 'date',
|
||||
value: dateRange.value[1].format('YYYY-MM-DD HH:mm:ss')
|
||||
value: dateRange.value![1].format('YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -229,324 +253,79 @@ const fetchData = async () => {
|
||||
}
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
// ==================== 数据请求 ====================
|
||||
const fetchData = async () => {
|
||||
if (!dateRange.value) return;
|
||||
|
||||
isLoading.value = true;
|
||||
|
||||
try {
|
||||
const res = await getMonitorData(params);
|
||||
const mainApi = apiConfig[activeTabKey.value] || getMonitorData;
|
||||
|
||||
if (activeTabKey.value === 'swjc.tabs.jcsj') {
|
||||
const [mainRes, powerStationRes] = await Promise.all([
|
||||
mainApi(buildFilterParams()),
|
||||
getMonitorDataWaterTempPowerStation({
|
||||
stcd: modelStore.params.stcd
|
||||
})
|
||||
]);
|
||||
|
||||
const mainData = mainRes?.data?.data || mainRes?.data?.records || [];
|
||||
|
||||
// 根据 powerStationRes.data 控制 checkbox 显示/隐藏
|
||||
showSummaryCheckbox.value = !!powerStationRes?.data?.ioWtrv;
|
||||
showDeepCheckbox.value = !!powerStationRes?.data?.hasRstcdWtvt;
|
||||
|
||||
// 数据按时间倒序显示(最新的在前)
|
||||
tableData.value = [...mainData].reverse();
|
||||
// 图表数据保持升序
|
||||
chartData.value = mainData;
|
||||
} else {
|
||||
const res = await mainApi(buildFilterParams());
|
||||
const rawData = res?.data?.data || res?.data?.records || [];
|
||||
|
||||
// 数据按时间倒序显示(最新的在前,1月1号最后)
|
||||
const reversedData = [...rawData].reverse();
|
||||
tableData.value = reversedData;
|
||||
updateChart(rawData); // 图表仍按升序渲染
|
||||
// 数据按时间倒序显示(最新的在前)
|
||||
tableData.value = [...rawData].reverse();
|
||||
// 图表数据保持升序
|
||||
chartData.value = rawData;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取数据失败:', error);
|
||||
tableData.value = [];
|
||||
chartData.value = [];
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 查询按钮点击事件
|
||||
const handleSearch = () => {
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// ==================== 图表相关 ====================
|
||||
const updateChart = (data: any[]) => {
|
||||
if (!chartInstance) return;
|
||||
|
||||
if (!data || data.length === 0) {
|
||||
chartInstance.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// 按时间升序
|
||||
const sorted = [...data].sort(
|
||||
(a, b) => new Date(a.tm).getTime() - new Date(b.tm).getTime()
|
||||
);
|
||||
|
||||
const xAxisData = sorted.map(item => dayjs(item.tm).format('HH:mm'));
|
||||
const rzData = sorted.map(item => item.rz);
|
||||
const dzData = sorted.map(item => item.dz);
|
||||
const qiData = sorted.map(item => item.qi);
|
||||
const qoData = sorted.map(item => item.qo);
|
||||
const qecData = sorted.map(item => item.qec);
|
||||
const qecLimitData = sorted.map(item => item.qecLimit);
|
||||
|
||||
// 计算水位 Y 轴最大值(左侧)
|
||||
const waterValues = [...rzData, ...dzData].filter(
|
||||
v => v !== null && v !== undefined
|
||||
);
|
||||
const waterMax = waterValues.length > 0 ? Math.max(...waterValues) : 10;
|
||||
const waterYMax = Math.ceil(waterMax * 1.1);
|
||||
const waterYMin = Math.floor(Math.min(...waterValues) * 0.95);
|
||||
|
||||
// 计算流量 Y 轴最大值(右侧)
|
||||
const flowValues = [...qiData, ...qoData, ...qecData, ...qecLimitData].filter(
|
||||
v => v !== null && v !== undefined
|
||||
);
|
||||
const flowMax = flowValues.length > 0 ? Math.max(...flowValues) : 10;
|
||||
const flowYMax = Math.ceil(flowMax * 1.1);
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(50, 50, 50, 0.9)',
|
||||
textStyle: { color: '#fff', fontSize: 12 },
|
||||
axisPointer: { type: 'cross' },
|
||||
formatter: (params: any) => {
|
||||
if (!params || params.length === 0) return '';
|
||||
const dataIndex = params[0].dataIndex;
|
||||
const fullTime = sorted[dataIndex]?.tm
|
||||
? dayjs(sorted[dataIndex].tm).format('YYYY-MM-DD HH:mm:ss')
|
||||
: '';
|
||||
let html = `<div style="font-size:16px;margin-bottom:8px;">${fullTime}</div>`;
|
||||
// 系列名称对应的格式化规则(与表格保持一致)
|
||||
const formatRules: Record<
|
||||
string,
|
||||
{ format: (v: number) => string; unit: string }
|
||||
> = {
|
||||
坝上水位: { format: v => v.toFixed(2), unit: '(m)' },
|
||||
坝下水位: { format: v => v.toFixed(2), unit: '(m)' },
|
||||
入库流量: { format: v => String(Math.round(v)), unit: '(m³/s)' },
|
||||
出库流量: { format: v => String(Number(v)), unit: '(m³/s)' },
|
||||
生态流量: { format: v => v.toFixed(1), unit: '(m³/s)' },
|
||||
生态流量限值: { format: v => v.toFixed(1), unit: '(m³/s)' }
|
||||
};
|
||||
params.forEach((param: any) => {
|
||||
if (param.value == null) return;
|
||||
const rule = Object.entries(formatRules).find(([key]) =>
|
||||
param.seriesName.includes(key)
|
||||
);
|
||||
const displayValue = rule
|
||||
? rule[1].format(Number(param.value))
|
||||
: param.value;
|
||||
const unit = rule ? rule[1].unit : '';
|
||||
html += `
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin:4px 0;">
|
||||
<span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:${param.color};margin-right:8px;"></span>
|
||||
<span style="flex:1;font-size:14px;text-align:left;margin-right:6px;">${param.seriesName}: </span>
|
||||
<span style="font-size:14px;min-width:60px;text-align:right;"><strong>${displayValue}</strong> ${unit}</span>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
return html;
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
type: 'scroll',
|
||||
top: 10,
|
||||
data: chartLegendData.value,
|
||||
textStyle: { fontSize: 12 },
|
||||
selected: {
|
||||
坝上水位: false,
|
||||
坝下水位: false,
|
||||
入库流量: true,
|
||||
出库流量: true,
|
||||
生态流量: false,
|
||||
生态流量限值: false
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: 60,
|
||||
right: 60,
|
||||
top: 80,
|
||||
bottom: 60
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: xAxisData,
|
||||
axisLine: { lineStyle: { color: '#000000' } },
|
||||
axisTick: { show: false },
|
||||
axisLabel: {
|
||||
fontSize: 12
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: { color: '#bfbfbf', type: 'solid' }
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
// 左侧 Y 轴:水位
|
||||
{
|
||||
name: '水位',
|
||||
type: 'value',
|
||||
position: 'left',
|
||||
axisLine: { lineStyle: { color: '#000000' } },
|
||||
alignTicks: true,
|
||||
scale: true,
|
||||
splitNumber: 9,
|
||||
boundaryGap: ['10%', 0]
|
||||
},
|
||||
// 右侧 Y 轴:流量
|
||||
{
|
||||
name: '流量',
|
||||
type: 'value',
|
||||
position: 'right',
|
||||
axisLine: { lineStyle: { color: '#000000' } },
|
||||
alignTicks: true,
|
||||
scale: true,
|
||||
splitNumber: 9,
|
||||
boundaryGap: ['10%', 0]
|
||||
}
|
||||
],
|
||||
series: [
|
||||
// 水位系列(使用左侧 Y 轴)
|
||||
{
|
||||
name: '坝上水位',
|
||||
type: 'line',
|
||||
yAxisIndex: 0,
|
||||
data: rzData,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
lineStyle: { color: '#56C2E3', width: 2 },
|
||||
itemStyle: { color: '#56C2E3' },
|
||||
markPoint: {
|
||||
data: [
|
||||
{ type: 'max', name: 'Max' },
|
||||
{ type: 'min', name: 'Min' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '坝下水位',
|
||||
type: 'line',
|
||||
yAxisIndex: 0,
|
||||
data: dzData,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
lineStyle: { color: '#7399C6', width: 2 },
|
||||
itemStyle: { color: '#7399C6' },
|
||||
markPoint: {
|
||||
data: [
|
||||
{ type: 'max', name: 'Max' },
|
||||
{ type: 'min', name: 'Min' }
|
||||
]
|
||||
}
|
||||
},
|
||||
// 流量系列(使用右侧 Y 轴)
|
||||
{
|
||||
name: '入库流量',
|
||||
type: 'line',
|
||||
yAxisIndex: 1,
|
||||
data: qiData,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
lineStyle: { color: '#4B79AB', width: 2 },
|
||||
itemStyle: { color: '#4B79AB' },
|
||||
markPoint: {
|
||||
data: [
|
||||
{ type: 'max', name: 'Max' },
|
||||
{ type: 'min', name: 'Min' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '出库流量',
|
||||
type: 'line',
|
||||
yAxisIndex: 1,
|
||||
data: qoData,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
lineStyle: { color: '#78C300', width: 2 },
|
||||
itemStyle: { color: '#78C300' },
|
||||
markPoint: {
|
||||
data: [
|
||||
{ type: 'max', name: 'Max' },
|
||||
{ type: 'min', name: 'Min' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '生态流量',
|
||||
type: 'line',
|
||||
yAxisIndex: 1,
|
||||
data: qecData,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
lineStyle: { color: '#00A050', width: 2 },
|
||||
itemStyle: { color: '#00A050' },
|
||||
markPoint: {
|
||||
data: [
|
||||
{ type: 'max', name: 'Max' },
|
||||
{ type: 'min', name: 'Min' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '生态流量限值',
|
||||
type: 'line',
|
||||
yAxisIndex: 1,
|
||||
data: qecLimitData,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
lineStyle: { color: '#F7A737', width: 2 },
|
||||
itemStyle: { color: '#F7A737' },
|
||||
markPoint: {
|
||||
data: [
|
||||
{ type: 'max', name: 'Max' },
|
||||
{ type: 'min', name: 'Min' }
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
xAxisIndex: [0],
|
||||
throttle: 50,
|
||||
start: 0,
|
||||
end: 100
|
||||
}
|
||||
],
|
||||
toolbox: {
|
||||
show: true,
|
||||
feature: {
|
||||
saveAsImage: { title: '保存为图片', type: 'png', pixelRatio: 2 }
|
||||
},
|
||||
right: 20,
|
||||
top: 10
|
||||
}
|
||||
};
|
||||
|
||||
chartInstance.setOption(option, true);
|
||||
const handleExport = () => {
|
||||
// 导出数据
|
||||
};
|
||||
|
||||
const initChart = () => {
|
||||
if (!chartRef.value) return;
|
||||
if (chartInstance) {
|
||||
chartInstance.dispose();
|
||||
}
|
||||
chartInstance = echarts.init(chartRef.value);
|
||||
};
|
||||
// Tab 切换时重置日期范围
|
||||
const handleTabChange = (key: string) => {
|
||||
const days = defaultDateRangeConfig[key]?.days || 30;
|
||||
const endDate = dayjs();
|
||||
let startDate = dayjs().subtract(days, 'day');
|
||||
|
||||
const handleResize = () => {
|
||||
if (chartInstance) {
|
||||
chartInstance.resize();
|
||||
if (key === 'swjc.tabs.jcsj') {
|
||||
startDate = startDate.startOf('day');
|
||||
}
|
||||
};
|
||||
|
||||
const destroyChart = () => {
|
||||
if (chartInstance) {
|
||||
chartInstance.dispose();
|
||||
chartInstance = null;
|
||||
}
|
||||
window.removeEventListener('resize', handleResize);
|
||||
dateRange.value = [startDate, endDate];
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// ==================== 初始化 ====================
|
||||
const initData = () => {
|
||||
if (hasLoaded.value) return;
|
||||
fetchData();
|
||||
setTimeout(() => {
|
||||
initChart();
|
||||
}, 200);
|
||||
hasLoaded.value = true;
|
||||
};
|
||||
|
||||
@ -574,20 +353,29 @@ onMounted(() => {
|
||||
window.addEventListener('resize', handleResize);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
destroyChart();
|
||||
window.removeEventListener('resize', handleResize);
|
||||
});
|
||||
const handleResize = () => {
|
||||
// 图表组件自己处理 resize
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.monitor-info {
|
||||
width: 100%;
|
||||
min-height: 600px;
|
||||
position: relative;
|
||||
:deep(.ant-tabs-nav) {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.checkbox-group {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.summary-tip-icon {
|
||||
color: rgb(53, 169, 255);
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
width: 100%;
|
||||
margin-bottom: 12px;
|
||||
@ -599,6 +387,12 @@ onUnmounted(() => {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
.tab-checkbox {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
left: 30%;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
width: 100%;
|
||||
@ -608,7 +402,7 @@ onUnmounted(() => {
|
||||
display: flex;
|
||||
height: 600px;
|
||||
|
||||
.chart-wrapper {
|
||||
:deep(.chart-container) {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
@ -621,6 +415,7 @@ onUnmounted(() => {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 10px;
|
||||
overflow: hidden;
|
||||
overflow-x: auto;
|
||||
border-left: 1px solid #dcdfe6;
|
||||
margin-left: 10px;
|
||||
@ -628,4 +423,7 @@ onUnmounted(() => {
|
||||
}
|
||||
}
|
||||
}
|
||||
.summary-row {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -0,0 +1,315 @@
|
||||
<template>
|
||||
<div class="chart-container" ref="chartRef"></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch, onMounted, onUnmounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array as () => any[],
|
||||
default: () => []
|
||||
}
|
||||
});
|
||||
|
||||
const chartRef = ref<HTMLDivElement | null>(null);
|
||||
let chartInstance: echarts.ECharts | null = null;
|
||||
|
||||
const formatRules: Record<string, { format: (v: number) => string; unit: string }> = {
|
||||
坝上水位: { format: v => v.toFixed(2), unit: '(m)' },
|
||||
坝下水位: { format: v => v.toFixed(2), unit: '(m)' },
|
||||
入库流量: { format: v => String(Math.round(v)), unit: '(m³/s)' },
|
||||
出库流量: { format: v => String(Number(v)), unit: '(m³/s)' },
|
||||
生态流量: { format: v => v.toFixed(1), unit: '(m³/s)' },
|
||||
生态流量限值: { format: v => v.toFixed(1), unit: '(m³/s)' }
|
||||
};
|
||||
|
||||
const updateChart = (data: any[]) => {
|
||||
if (!chartInstance) return;
|
||||
|
||||
if (!data || data.length === 0) {
|
||||
chartInstance.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
const sorted = [...data].sort(
|
||||
(a, b) => new Date(a.tm).getTime() - new Date(b.tm).getTime()
|
||||
);
|
||||
|
||||
const xAxisData = sorted.map(item => dayjs(item.tm).format('HH:mm'));
|
||||
const rzData = sorted.map(item => item.rz);
|
||||
const dzData = sorted.map(item => item.dz);
|
||||
const qiData = sorted.map(item => item.qi);
|
||||
const qoData = sorted.map(item => item.qo);
|
||||
const qecData = sorted.map(item => item.qec);
|
||||
const qecLimitData = sorted.map(item => item.qecLimit);
|
||||
|
||||
const waterValues = [...rzData, ...dzData].filter(
|
||||
v => v !== null && v !== undefined
|
||||
);
|
||||
const waterMax = waterValues.length > 0 ? Math.max(...waterValues) : 10;
|
||||
const waterYMax = Math.ceil(waterMax * 1.1);
|
||||
const waterYMin = Math.floor(Math.min(...waterValues) * 0.95);
|
||||
|
||||
const flowValues = [...qiData, ...qoData, ...qecData, ...qecLimitData].filter(
|
||||
v => v !== null && v !== undefined
|
||||
);
|
||||
const flowMax = flowValues.length > 0 ? Math.max(...flowValues) : 10;
|
||||
const flowYMax = Math.ceil(flowMax * 1.1);
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(50, 50, 50, 0.9)',
|
||||
textStyle: { color: '#fff', fontSize: 12 },
|
||||
axisPointer: { type: 'cross' },
|
||||
formatter: (params: any) => {
|
||||
if (!params || params.length === 0) return '';
|
||||
const dataIndex = params[0].dataIndex;
|
||||
const fullTime = sorted[dataIndex]?.tm
|
||||
? dayjs(sorted[dataIndex].tm).format('YYYY-MM-DD HH:mm:ss')
|
||||
: '';
|
||||
let html = `<div style="font-size:16px;margin-bottom:8px;">${fullTime}</div>`;
|
||||
params.forEach((param: any) => {
|
||||
if (param.value == null) return;
|
||||
const rule = Object.entries(formatRules).find(([key]) =>
|
||||
param.seriesName.includes(key)
|
||||
);
|
||||
const displayValue = rule
|
||||
? rule[1].format(Number(param.value))
|
||||
: param.value;
|
||||
const unit = rule ? rule[1].unit : '';
|
||||
html += `
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin:4px 0;">
|
||||
<span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:${param.color};margin-right:8px;"></span>
|
||||
<span style="flex:1;font-size:14px;text-align:left;margin-right:6px;">${param.seriesName}: </span>
|
||||
<span style="font-size:14px;min-width:60px;text-align:right;"><strong>${displayValue}</strong> ${unit}</span>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
return html;
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
type: 'scroll',
|
||||
top: 10,
|
||||
data: ['坝上水位', '坝下水位', '入库流量', '出库流量', '生态流量', '生态流量限值'],
|
||||
textStyle: { fontSize: 12 },
|
||||
selected: {
|
||||
'坝上水位': false,
|
||||
'坝下水位': false,
|
||||
'入库流量': true,
|
||||
'出库流量': true,
|
||||
'生态流量': false,
|
||||
'生态流量限值': false
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: 60,
|
||||
right: 60,
|
||||
top: 80,
|
||||
bottom: 60
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: xAxisData,
|
||||
axisLine: { lineStyle: { color: '#000000' } },
|
||||
axisTick: { show: false },
|
||||
axisLabel: { fontSize: 12 },
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: { color: '#bfbfbf', type: 'solid' }
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
name: '水位',
|
||||
type: 'value',
|
||||
position: 'left',
|
||||
axisLine: { lineStyle: { color: '#000000' } },
|
||||
alignTicks: true,
|
||||
scale: true,
|
||||
splitNumber: 9,
|
||||
boundaryGap: ['10%', 0]
|
||||
},
|
||||
{
|
||||
name: '流量',
|
||||
type: 'value',
|
||||
position: 'right',
|
||||
axisLine: { lineStyle: { color: '#000000' } },
|
||||
alignTicks: true,
|
||||
scale: true,
|
||||
splitNumber: 9,
|
||||
boundaryGap: ['10%', 0]
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '坝上水位',
|
||||
type: 'line',
|
||||
yAxisIndex: 0,
|
||||
data: rzData,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
lineStyle: { color: '#56C2E3', width: 2 },
|
||||
itemStyle: { color: '#56C2E3' },
|
||||
markPoint: {
|
||||
data: [
|
||||
{ type: 'max', name: 'Max' },
|
||||
{ type: 'min', name: 'Min' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '坝下水位',
|
||||
type: 'line',
|
||||
yAxisIndex: 0,
|
||||
data: dzData,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
lineStyle: { color: '#7399C6', width: 2 },
|
||||
itemStyle: { color: '#7399C6' },
|
||||
markPoint: {
|
||||
data: [
|
||||
{ type: 'max', name: 'Max' },
|
||||
{ type: 'min', name: 'Min' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '入库流量',
|
||||
type: 'line',
|
||||
yAxisIndex: 1,
|
||||
data: qiData,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
lineStyle: { color: '#4B79AB', width: 2 },
|
||||
itemStyle: { color: '#4B79AB' },
|
||||
markPoint: {
|
||||
data: [
|
||||
{ type: 'max', name: 'Max' },
|
||||
{ type: 'min', name: 'Min' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '出库流量',
|
||||
type: 'line',
|
||||
yAxisIndex: 1,
|
||||
data: qoData,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
lineStyle: { color: '#78C300', width: 2 },
|
||||
itemStyle: { color: '#78C300' },
|
||||
markPoint: {
|
||||
data: [
|
||||
{ type: 'max', name: 'Max' },
|
||||
{ type: 'min', name: 'Min' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '生态流量',
|
||||
type: 'line',
|
||||
yAxisIndex: 1,
|
||||
data: qecData,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
lineStyle: { color: '#00A050', width: 2 },
|
||||
itemStyle: { color: '#00A050' },
|
||||
markPoint: {
|
||||
data: [
|
||||
{ type: 'max', name: 'Max' },
|
||||
{ type: 'min', name: 'Min' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '生态流量限值',
|
||||
type: 'line',
|
||||
yAxisIndex: 1,
|
||||
data: qecLimitData,
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 4,
|
||||
lineStyle: { color: '#F7A737', width: 2 },
|
||||
itemStyle: { color: '#F7A737' },
|
||||
markPoint: {
|
||||
data: [
|
||||
{ type: 'max', name: 'Max' },
|
||||
{ type: 'min', name: 'Min' }
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
xAxisIndex: [0],
|
||||
throttle: 50,
|
||||
start: 0,
|
||||
end: 100
|
||||
}
|
||||
],
|
||||
toolbox: {
|
||||
show: true,
|
||||
feature: {
|
||||
saveAsImage: { title: '保存为图片', type: 'png', pixelRatio: 2 }
|
||||
},
|
||||
right: 20,
|
||||
top: 10
|
||||
}
|
||||
};
|
||||
|
||||
chartInstance.setOption(option, true);
|
||||
};
|
||||
|
||||
const initChart = () => {
|
||||
if (!chartRef.value) return;
|
||||
if (chartInstance) {
|
||||
chartInstance.dispose();
|
||||
}
|
||||
chartInstance = echarts.init(chartRef.value);
|
||||
};
|
||||
|
||||
const handleResize = () => {
|
||||
if (chartInstance) {
|
||||
chartInstance.resize();
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
newData => {
|
||||
updateChart(newData);
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
initChart();
|
||||
window.addEventListener('resize', handleResize);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (chartInstance) {
|
||||
chartInstance.dispose();
|
||||
chartInstance = null;
|
||||
}
|
||||
window.removeEventListener('resize', handleResize);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.chart-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,505 @@
|
||||
<template>
|
||||
<div class="chart-container" ref="chartRef"></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch, onMounted, onUnmounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array as () => any[],
|
||||
default: () => []
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'base' // 'base' | 'deep' | 'summary'
|
||||
}
|
||||
});
|
||||
|
||||
const chartRef = ref<HTMLDivElement | null>(null);
|
||||
let chartInstance: echarts.ECharts | null = null;
|
||||
|
||||
// 计算是否需要错位
|
||||
function shouldStagger(width: number, dataLen: number) {
|
||||
const labelWidth = 100;
|
||||
const maxLabels = Math.floor(width / labelWidth);
|
||||
return dataLen > maxLabels;
|
||||
}
|
||||
|
||||
function getAxisLabelConfig(chartWidth: number, xAxisData: string[]) {
|
||||
const dataLen = xAxisData.length;
|
||||
const needStagger = shouldStagger(chartWidth, dataLen);
|
||||
|
||||
return {
|
||||
fontSize: 12,
|
||||
interval: 'auto',
|
||||
formatter: (value: string, index: number) => {
|
||||
const [date, time] = value.split(' ');
|
||||
if (needStagger) {
|
||||
if (index % 2 === 0) {
|
||||
return `${date}\n${time}\n `;
|
||||
} else {
|
||||
return ` \n${date}\n${time}`;
|
||||
}
|
||||
} else {
|
||||
return `${date}\n${time}`;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const updateChart = (data: any[]) => {
|
||||
if (!chartInstance) return;
|
||||
if (!data || data.length === 0) {
|
||||
chartInstance.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
const sorted = [...data].sort(
|
||||
(a, b) => new Date(a.tm).getTime() - new Date(b.tm).getTime()
|
||||
);
|
||||
|
||||
const xAxisData = sorted.map(item =>
|
||||
dayjs(item.tm).format('YYYY-MM-DD HH:mm')
|
||||
);
|
||||
|
||||
const width = chartRef.value?.clientWidth || 0;
|
||||
const axisLabelConfig = getAxisLabelConfig(width, xAxisData);
|
||||
|
||||
// ==================== 基础模式 ====================
|
||||
if (props.mode === 'base') {
|
||||
const wtData = sorted.map(item => item.wt);
|
||||
const option = {
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(50, 50, 50, 0.9)',
|
||||
textStyle: { color: '#fff', fontSize: 12 },
|
||||
axisPointer: { type: 'cross' },
|
||||
formatter: (params: any) => {
|
||||
if (!params || params.length === 0) return '';
|
||||
const dataIndex = params[0].dataIndex;
|
||||
const fullTime = sorted[dataIndex]?.tm
|
||||
? dayjs(sorted[dataIndex].tm).format('YYYY-MM-DD HH:mm')
|
||||
: '';
|
||||
let html = `<div style="font-size:16px;margin-bottom:8px;">${fullTime}</div>`;
|
||||
params.forEach((param: any) => {
|
||||
const value =
|
||||
param.value != null ? Number(param.value).toFixed(1) : '-';
|
||||
html += `
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin:4px 0;">
|
||||
<span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:${param.color};margin-right:8px;"></span>
|
||||
<span style="flex:1;font-size:14px;text-align:left;margin-right:6px;">水温: </span>
|
||||
<span style="font-size:14px;min-width:60px;text-align:right;"><strong>${value}</strong> °C</span>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
return html;
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
type: 'scroll',
|
||||
top: 10,
|
||||
data: ['水温'],
|
||||
textStyle: { fontSize: 12 }
|
||||
},
|
||||
grid: { left: 60, right: 40, top: 80, bottom: 80 },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: xAxisData,
|
||||
axisLine: { lineStyle: { color: '#000000' } },
|
||||
axisTick: { show: false },
|
||||
axisLabel: axisLabelConfig,
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: { color: '#bfbfbf', type: 'solid' }
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
name: '水温(°C)',
|
||||
type: 'value',
|
||||
axisLine: { lineStyle: { color: '#000000' } },
|
||||
scale: true,
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: { color: '#bfbfbf', type: 'solid' }
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '水温',
|
||||
type: 'line',
|
||||
data: wtData,
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
lineStyle: { color: '#4B79AB', width: 2 },
|
||||
itemStyle: { color: '#4B79AB' },
|
||||
areaStyle: { color: '#85A9D0' }
|
||||
}
|
||||
],
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
xAxisIndex: [0],
|
||||
throttle: 50,
|
||||
start: 0,
|
||||
end: 100
|
||||
}
|
||||
],
|
||||
toolbox: {
|
||||
show: true,
|
||||
feature: {
|
||||
saveAsImage: { title: '保存为图片', type: 'png', pixelRatio: 2 }
|
||||
},
|
||||
right: 20,
|
||||
top: 10
|
||||
}
|
||||
};
|
||||
chartInstance.setOption(option, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// ==================== 等深模式 ====================
|
||||
if (props.mode === 'deep') {
|
||||
const wtData = sorted.map(item => item.wt);
|
||||
const depthData = sorted.map(item => item?.wtvtDataVo?.wthg);
|
||||
const option = {
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(50, 50, 50, 0.9)',
|
||||
textStyle: { color: '#fff', fontSize: 12 },
|
||||
axisPointer: { type: 'cross' },
|
||||
formatter: (params: any) => {
|
||||
if (!params || params.length === 0) return '';
|
||||
const dataIndex = params[0].dataIndex;
|
||||
const fullTime = sorted[dataIndex]?.tm
|
||||
? dayjs(sorted[dataIndex].tm).format('YYYY-MM-DD HH:mm')
|
||||
: '';
|
||||
let html = `<div style="font-size:16px;margin-bottom:8px;">${fullTime}</div>`;
|
||||
params.forEach((param: any) => {
|
||||
const value =
|
||||
param.value != null
|
||||
? param.seriesName.includes('水深')
|
||||
? Number(param.value).toFixed(2)
|
||||
: Number(param.value).toFixed(1)
|
||||
: '-';
|
||||
const unit = param.seriesName.includes('水深') ? 'm' : '°C';
|
||||
html += `
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin:4px 0;">
|
||||
<span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:${param.color};margin-right:8px;"></span>
|
||||
<span style="flex:1;font-size:14px;text-align:left;margin-right:6px;">${param.seriesName}: </span>
|
||||
<span style="font-size:14px;min-width:60px;text-align:right;"><strong>${value}</strong> ${unit}</span>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
return html;
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
type: 'scroll',
|
||||
top: 10,
|
||||
data: ['水温', '等温水深'],
|
||||
textStyle: { fontSize: 12 }
|
||||
},
|
||||
grid: { left: 60, right: 60, top: 80, bottom: 80 },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: xAxisData,
|
||||
axisLine: { lineStyle: { color: '#000000' } },
|
||||
axisTick: { show: false },
|
||||
axisLabel: axisLabelConfig,
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: { color: '#bfbfbf', type: 'solid' }
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
// 左轴:水温
|
||||
{
|
||||
name: '水温(°C)',
|
||||
type: 'value',
|
||||
position: 'left',
|
||||
axisLine: { lineStyle: { color: '#000000' } },
|
||||
scale: true,
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: { color: '#bfbfbf', type: 'solid' }
|
||||
}
|
||||
},
|
||||
// 右轴:水深
|
||||
{
|
||||
name: '水深(m)',
|
||||
type: 'value',
|
||||
position: 'right',
|
||||
axisLine: { lineStyle: { color: '#000000' } },
|
||||
scale: true,
|
||||
splitLine: { show: false }
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '水温',
|
||||
type: 'line',
|
||||
yAxisIndex: 0,
|
||||
data: wtData,
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
lineStyle: { color: '#4B79AB', width: 2 },
|
||||
itemStyle: { color: '#4B79AB' }
|
||||
},
|
||||
{
|
||||
name: '等温水深',
|
||||
type: 'line',
|
||||
yAxisIndex: 1,
|
||||
data: depthData,
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
lineStyle: { color: '#AB7AE5', width: 2 },
|
||||
itemStyle: { color: '#AB7AE5' }
|
||||
}
|
||||
],
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
xAxisIndex: [0],
|
||||
throttle: 50,
|
||||
start: 0,
|
||||
end: 100
|
||||
}
|
||||
],
|
||||
toolbox: {
|
||||
show: true,
|
||||
feature: {
|
||||
saveAsImage: { title: '保存为图片', type: 'png', pixelRatio: 2 }
|
||||
},
|
||||
right: 20,
|
||||
top: 10
|
||||
}
|
||||
};
|
||||
chartInstance.setOption(option, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// ==================== 综合分析模式 ====================
|
||||
if (props.mode === 'summary') {
|
||||
const outWtData = sorted.map(item => item.wt);
|
||||
const inWtData = sorted.map(item => item?.iwtDataVo?.wt);
|
||||
const natureTmpData = sorted.map(item => item.natureTmp);
|
||||
const airTempData = sorted.map(item => item?.tmpDataVo?.at);
|
||||
const outFlowData = sorted.map(item => item?.hydropwDataVo?.qo);
|
||||
const inFlowData = sorted.map(item => item?.hydropwDataVo?.qi);
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(50, 50, 50, 0.9)',
|
||||
textStyle: { color: '#fff', fontSize: 12 },
|
||||
axisPointer: { type: 'cross' },
|
||||
formatter: (params: any) => {
|
||||
if (!params || params.length === 0) return '';
|
||||
const dataIndex = params[0].dataIndex;
|
||||
const fullTime = sorted[dataIndex]?.tm
|
||||
? dayjs(sorted[dataIndex].tm).format('YYYY-MM-DD HH:mm')
|
||||
: '';
|
||||
let html = `<div style="font-size:16px;margin-bottom:8px;">${fullTime}</div>`;
|
||||
params.forEach((param: any) => {
|
||||
const isFlow = param.seriesName.includes('流量');
|
||||
const value =
|
||||
param.value != null
|
||||
? isFlow
|
||||
? Number(param.value).toFixed(3)
|
||||
: Number(param.value).toFixed(1)
|
||||
: '-';
|
||||
const unit = isFlow ? 'm³/s' : '°C';
|
||||
html += `
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin:4px 0;">
|
||||
<span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:${param.color};margin-right:8px;"></span>
|
||||
<span style="flex:1;font-size:14px;text-align:left;margin-right:6px;">${param.seriesName}: </span>
|
||||
<span style="font-size:14px;min-width:60px;text-align:right;"><strong>${value}</strong> ${unit}</span>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
return html;
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
type: 'scroll',
|
||||
top: 10,
|
||||
data: [
|
||||
'出库水温',
|
||||
'入库水温',
|
||||
'天然水温',
|
||||
'气温',
|
||||
'出库流量',
|
||||
'入库流量'
|
||||
],
|
||||
textStyle: { fontSize: 12 }
|
||||
},
|
||||
grid: { left: 60, right: 60, top: 80, bottom: 80 },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: xAxisData,
|
||||
axisLine: { lineStyle: { color: '#000000' } },
|
||||
axisTick: { show: false },
|
||||
axisLabel: axisLabelConfig,
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: { color: '#bfbfbf', type: 'solid' }
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
// 左轴:水温
|
||||
{
|
||||
name: '水温(°C)',
|
||||
type: 'value',
|
||||
position: 'left',
|
||||
axisLine: { lineStyle: { color: '#000000' } },
|
||||
scale: true,
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: { color: '#bfbfbf', type: 'solid' }
|
||||
}
|
||||
},
|
||||
// 右轴:流量
|
||||
{
|
||||
name: '流量(m³/s)',
|
||||
type: 'value',
|
||||
position: 'right',
|
||||
axisLine: { lineStyle: { color: '#000000' } },
|
||||
scale: true,
|
||||
splitLine: { show: false }
|
||||
}
|
||||
],
|
||||
series: [
|
||||
// 水温系列(左轴)
|
||||
{
|
||||
name: '出库水温',
|
||||
type: 'line',
|
||||
yAxisIndex: 0,
|
||||
data: outWtData,
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
lineStyle: { color: '#78C300', width: 2 },
|
||||
itemStyle: { color: '#78C300' }
|
||||
},
|
||||
{
|
||||
name: '入库水温',
|
||||
type: 'line',
|
||||
yAxisIndex: 0,
|
||||
data: inWtData,
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
lineStyle: { color: '#9557A4', width: 2 },
|
||||
itemStyle: { color: '#9557A4' }
|
||||
},
|
||||
{
|
||||
name: '天然水温',
|
||||
type: 'line',
|
||||
yAxisIndex: 0,
|
||||
data: natureTmpData,
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
lineStyle: { color: '#DF91AB', width: 2 },
|
||||
itemStyle: { color: '#DF91AB' }
|
||||
},
|
||||
{
|
||||
name: '气温',
|
||||
type: 'line',
|
||||
yAxisIndex: 0,
|
||||
data: airTempData,
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
lineStyle: { color: '#7399C6', width: 2 },
|
||||
itemStyle: { color: '#7399C6' }
|
||||
},
|
||||
// 流量系列(右轴)
|
||||
{
|
||||
name: '出库流量',
|
||||
type: 'line',
|
||||
yAxisIndex: 1,
|
||||
data: outFlowData,
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
lineStyle: { color: '#56C2E3', width: 2 },
|
||||
itemStyle: { color: '#56C2E3' }
|
||||
},
|
||||
{
|
||||
name: '入库流量',
|
||||
type: 'line',
|
||||
yAxisIndex: 1,
|
||||
data: inFlowData,
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
lineStyle: { color: '#DBB629', width: 2 },
|
||||
itemStyle: { color: '#DBB629' }
|
||||
}
|
||||
],
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
xAxisIndex: [0],
|
||||
throttle: 50,
|
||||
start: 0,
|
||||
end: 100
|
||||
}
|
||||
],
|
||||
toolbox: {
|
||||
show: true,
|
||||
feature: {
|
||||
saveAsImage: { title: '保存为图片', type: 'png', pixelRatio: 2 }
|
||||
},
|
||||
right: 20,
|
||||
top: 10
|
||||
}
|
||||
};
|
||||
chartInstance.setOption(option, true);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const initChart = () => {
|
||||
if (!chartRef.value) return;
|
||||
if (chartInstance) {
|
||||
chartInstance.dispose();
|
||||
}
|
||||
chartInstance = echarts.init(chartRef.value);
|
||||
};
|
||||
|
||||
const handleResize = () => {
|
||||
if (chartInstance) {
|
||||
chartInstance.resize();
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => [props.data, props.mode],
|
||||
() => {
|
||||
updateChart(props.data);
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
initChart();
|
||||
window.addEventListener('resize', handleResize);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (chartInstance) {
|
||||
chartInstance.dispose();
|
||||
chartInstance = null;
|
||||
}
|
||||
window.removeEventListener('resize', handleResize);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.chart-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,399 @@
|
||||
import { ref, computed } from 'vue';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
/**
|
||||
* 水温表格相关逻辑(Checkbox、表格列、合计行)
|
||||
*/
|
||||
export function useWaterTempTable(chartData: any[], activeTabKey: any) {
|
||||
const selectedColumns = ref<any[]>([]);
|
||||
|
||||
// ==================== Checkbox 配置 ====================
|
||||
const checkBoxOptions = [
|
||||
{ label: '综合分析', value: 'summary' },
|
||||
{ label: '等深水温', value: 'deep' }
|
||||
];
|
||||
|
||||
const showSummaryCheckbox = ref(false); // ioWtrv
|
||||
const showDeepCheckbox = ref(false); // hasRstcdWtvt
|
||||
const isDataEmpty = computed(
|
||||
() => !Array.isArray(chartData.value) || chartData.value.length === 0
|
||||
);
|
||||
|
||||
// 根据 powerStationRes 数据 + 互斥逻辑 动态过滤 checkbox 选项
|
||||
const filteredCheckBoxOptions = computed(() => {
|
||||
if (activeTabKey.value !== 'swjc.tabs.jcsj') return [];
|
||||
if (isDataEmpty.value) return [];
|
||||
|
||||
const selected = selectedColumns.value;
|
||||
const hasSelected = selected.length > 0;
|
||||
const selectedValue = selected[0];
|
||||
|
||||
return checkBoxOptions.filter(opt => {
|
||||
if (opt.value === 'summary' && !showSummaryCheckbox.value) return false;
|
||||
if (opt.value === 'deep' && !showDeepCheckbox.value) return false;
|
||||
if (hasSelected) {
|
||||
return opt.value === selectedValue;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
const isDeepMode = computed(() => selectedColumns.value.includes('deep'));
|
||||
const isSummaryMode = computed(() =>
|
||||
selectedColumns.value.includes('summary')
|
||||
);
|
||||
|
||||
const currentChartMode = computed(() => {
|
||||
if (isSummaryMode.value) return 'summary';
|
||||
if (isDeepMode.value) return 'deep';
|
||||
return 'base';
|
||||
});
|
||||
|
||||
// Checkbox 变化处理
|
||||
const handleCheckboxChange = (values: any[], fetchData: () => void) => {
|
||||
const hasSummary = values.includes('summary');
|
||||
const hasDeep = values.includes('deep');
|
||||
|
||||
if (hasSummary && hasDeep) {
|
||||
selectedColumns.value = [values[values.length - 1]];
|
||||
} else {
|
||||
selectedColumns.value = values;
|
||||
}
|
||||
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// ==================== 表格列配置 ====================
|
||||
const baseWaterTempColumns = [
|
||||
{
|
||||
title: '时间',
|
||||
dataIndex: 'tm',
|
||||
fixed: 'left',
|
||||
customRender: ({ text }: any) =>
|
||||
text ? dayjs(text).format('YYYY-MM-DD HH:mm') : '-'
|
||||
},
|
||||
{
|
||||
title: '水温(°C)',
|
||||
dataIndex: 'wt',
|
||||
summary: true,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text).toFixed(1) : '-'
|
||||
}
|
||||
];
|
||||
|
||||
const deepModeExtraColumns = [
|
||||
{
|
||||
title: '等温水深(m)',
|
||||
dataIndex: 'deep_wt',
|
||||
summary: true,
|
||||
customRender: ({ record }: any) => {
|
||||
const val = record?.wtvtDataVo?.wthg;
|
||||
return val !== undefined && val !== null ? Number(val).toFixed(2) : '-';
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '垂向水温(℃)',
|
||||
dataIndex: 'vert_wt',
|
||||
summary: true,
|
||||
customRender: ({ record }: any) => {
|
||||
const val = record?.wtvtDataVo?.vwt;
|
||||
return val !== undefined && val !== null ? Number(val).toFixed(1) : '-';
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const summaryModeColumns = [
|
||||
{
|
||||
title: '时间',
|
||||
dataIndex: 'tm',
|
||||
width: 130,
|
||||
fixed: 'left',
|
||||
customRender: ({ text }: any) =>
|
||||
text ? dayjs(text).format('YYYY-MM-DD HH:mm') : '-'
|
||||
},
|
||||
{
|
||||
title: '出库水温(℃)',
|
||||
dataIndex: 'wt',
|
||||
summary: true,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text).toFixed(1) : '-'
|
||||
},
|
||||
{
|
||||
title: '入库水温(℃)',
|
||||
dataIndex: 'iwt_wt',
|
||||
summary: true,
|
||||
customRender: ({ record }: any) =>
|
||||
record?.iwtDataVo?.wt !== undefined && record?.iwtDataVo?.wt !== null
|
||||
? Number(record.iwtDataVo.wt).toFixed(1)
|
||||
: '-'
|
||||
},
|
||||
{
|
||||
title: '天然水温(°C)',
|
||||
dataIndex: 'natureTmp',
|
||||
summary: true,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text).toFixed(1) : '-'
|
||||
},
|
||||
{
|
||||
title: '气温(℃)',
|
||||
dataIndex: 'tmp_at',
|
||||
summary: true,
|
||||
width: 80,
|
||||
customRender: ({ record }: any) =>
|
||||
record?.tmpDataVo?.at !== undefined && record?.tmpDataVo?.at !== null
|
||||
? Number(record.tmpDataVo.at).toFixed(1)
|
||||
: '-'
|
||||
},
|
||||
{
|
||||
title: '出库流量(m³/s)',
|
||||
dataIndex: 'hydropw_qo',
|
||||
summary: true,
|
||||
width: 120,
|
||||
customRender: ({ record }: any) =>
|
||||
record?.hydropwDataVo?.qo !== undefined &&
|
||||
record?.hydropwDataVo?.qo !== null
|
||||
? Number(record.hydropwDataVo.qo).toFixed(3)
|
||||
: '-'
|
||||
},
|
||||
{
|
||||
title: '入库流量(m³/s)',
|
||||
dataIndex: 'hydropw_qi',
|
||||
summary: true,
|
||||
width: 120,
|
||||
customRender: ({ record }: any) =>
|
||||
record?.hydropwDataVo?.qi !== undefined &&
|
||||
record?.hydropwDataVo?.qi !== null
|
||||
? Number(record.hydropwDataVo.qi).toFixed(3)
|
||||
: '-'
|
||||
}
|
||||
];
|
||||
|
||||
const tableColumnsConfig: Record<string, any[]> = {
|
||||
'dzxq.tabs.jcsj': [
|
||||
{
|
||||
title: '时间',
|
||||
dataIndex: 'tm',
|
||||
width: 180,
|
||||
fixed: 'left',
|
||||
customRender: ({ text }: any) =>
|
||||
text ? dayjs(text).format('YYYY-MM-DD HH:mm:ss') : '-'
|
||||
},
|
||||
{
|
||||
title: '坝上水位(m)',
|
||||
dataIndex: 'rz',
|
||||
width: 130,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text).toFixed(2) : '-'
|
||||
},
|
||||
{
|
||||
title: '坝下水位(m)',
|
||||
dataIndex: 'dz',
|
||||
width: 130,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text).toFixed(2) : '-'
|
||||
},
|
||||
{
|
||||
title: '入库流量(m³/s)',
|
||||
dataIndex: 'qi',
|
||||
width: 130,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Math.round(Number(text)) : '-'
|
||||
},
|
||||
{
|
||||
title: '出库流量(m³/s)',
|
||||
dataIndex: 'qo',
|
||||
width: 130,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text) : '-'
|
||||
},
|
||||
{
|
||||
title: '生态流量(m³/s)',
|
||||
dataIndex: 'qec',
|
||||
width: 130,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text).toFixed(1) : '-'
|
||||
},
|
||||
{
|
||||
title: '生态流量限值(m³/s)',
|
||||
dataIndex: 'qecLimit',
|
||||
width: 150,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text).toFixed(1) : '-'
|
||||
}
|
||||
],
|
||||
'swjc.tabs.jcsj': []
|
||||
};
|
||||
|
||||
const swjcColumns = computed(() => {
|
||||
if (isSummaryMode.value) {
|
||||
return summaryModeColumns;
|
||||
}
|
||||
if (isDeepMode.value) {
|
||||
return [...baseWaterTempColumns, ...deepModeExtraColumns];
|
||||
}
|
||||
return baseWaterTempColumns;
|
||||
});
|
||||
|
||||
const currentColumns = computed(() => {
|
||||
if (activeTabKey.value === 'swjc.tabs.jcsj') {
|
||||
return swjcColumns.value;
|
||||
}
|
||||
return (
|
||||
tableColumnsConfig[activeTabKey.value] ||
|
||||
tableColumnsConfig['dzxq.tabs.jcsj']
|
||||
);
|
||||
});
|
||||
|
||||
const tableScrollX = computed(() => {
|
||||
const columns = currentColumns.value;
|
||||
const totalWidth = columns.reduce(
|
||||
(sum: number, col: any) => sum + (col.width || 100),
|
||||
0
|
||||
);
|
||||
return totalWidth > 600 ? totalWidth : undefined;
|
||||
});
|
||||
|
||||
// ==================== 合计行配置 ====================
|
||||
const dataPathMap: Record<string, string> = {
|
||||
wt: 'wt',
|
||||
iwt_wt: 'iwtDataVo.wt',
|
||||
natureTmp: 'natureTmp',
|
||||
tmp_at: 'tmpDataVo.at',
|
||||
hydropw_qo: 'hydropwDataVo.qo',
|
||||
hydropw_qi: 'hydropwDataVo.qi',
|
||||
deep_wt: 'wtvtDataVo.wthg',
|
||||
vert_wt: 'wtvtDataVo.vwt'
|
||||
};
|
||||
|
||||
const summaryColumns = computed(() => {
|
||||
if (activeTabKey.value !== 'swjc.tabs.jcsj') return [];
|
||||
const cols = currentColumns.value
|
||||
.filter((col: any) => col.summary === true)
|
||||
.map((col: any, idx: number) => ({
|
||||
...col,
|
||||
summaryIndex: idx + 1
|
||||
}));
|
||||
return cols;
|
||||
});
|
||||
|
||||
const getNestedValue = (obj: any, path: string) => {
|
||||
if (!path || !obj) return undefined;
|
||||
return path.split('.').reduce((acc, key) => acc?.[key], obj);
|
||||
};
|
||||
|
||||
const calcSummary = (dataIndex: string, type: 'max' | 'min' | 'avg') => {
|
||||
const data = Array.isArray(chartData.value) ? chartData.value : [];
|
||||
if (!data || data.length === 0) return null;
|
||||
|
||||
const dataPath = dataPathMap[dataIndex] || dataIndex;
|
||||
const values = data
|
||||
.map((r: any) => {
|
||||
const val = getNestedValue(r, dataPath);
|
||||
return val !== null && val !== undefined && val !== '-'
|
||||
? Number(val)
|
||||
: NaN;
|
||||
})
|
||||
.filter((v: number) => !isNaN(v));
|
||||
|
||||
if (values.length === 0) return null;
|
||||
|
||||
if (type === 'max') return Math.max(...values);
|
||||
if (type === 'min') return Math.min(...values);
|
||||
return values.reduce((s, v) => s + v, 0) / values.length;
|
||||
};
|
||||
|
||||
const getSummaryTime = (dataIndex: string, type: 'max' | 'min') => {
|
||||
const data = Array.isArray(chartData.value) ? chartData.value : [];
|
||||
if (!data || data.length === 0) return '';
|
||||
|
||||
const dataPath = dataPathMap[dataIndex] || dataIndex;
|
||||
const records = data.filter((r: any) => {
|
||||
const val = getNestedValue(r, dataPath);
|
||||
return val !== null && val !== undefined && val !== '-';
|
||||
});
|
||||
if (records.length === 0) return '';
|
||||
|
||||
const target = Math[type](
|
||||
...records.map((r: any) => Number(getNestedValue(r, dataPath)))
|
||||
);
|
||||
const record = records.find(
|
||||
(r: any) => Number(getNestedValue(r, dataPath)) === target
|
||||
);
|
||||
return record?.tm ? dayjs(record.tm).format('YYYY-MM-DD HH:mm:ss') : '';
|
||||
};
|
||||
|
||||
const formatSummaryValue = (dataIndex: string, value: number | null) => {
|
||||
if (value === null) return '-';
|
||||
if (dataIndex.includes('qo') || dataIndex.includes('qi')) {
|
||||
return Number(value).toFixed(3);
|
||||
}
|
||||
if (dataIndex === 'deep_wt') {
|
||||
return Number(value).toFixed(2);
|
||||
}
|
||||
return Number(value).toFixed(1);
|
||||
};
|
||||
|
||||
const summaryRows = computed(() => {
|
||||
if (activeTabKey.value !== 'swjc.tabs.jcsj') return [];
|
||||
if (isDataEmpty.value) return [];
|
||||
|
||||
const rows = [
|
||||
{
|
||||
label: '最大值',
|
||||
showTime: true,
|
||||
cells: {} as Record<string, { value: string; time: string }>
|
||||
},
|
||||
{
|
||||
label: '最小值',
|
||||
showTime: true,
|
||||
cells: {} as Record<string, { value: string; time: string }>
|
||||
},
|
||||
{
|
||||
label: '平均值',
|
||||
showTime: false,
|
||||
cells: {} as Record<string, { value: string; time: string }>
|
||||
}
|
||||
];
|
||||
|
||||
summaryColumns.value.forEach((col: any) => {
|
||||
const dataIndex = col.dataIndex;
|
||||
const maxVal = calcSummary(dataIndex, 'max');
|
||||
const minVal = calcSummary(dataIndex, 'min');
|
||||
const avgVal = calcSummary(dataIndex, 'avg');
|
||||
|
||||
rows[0].cells[dataIndex] = {
|
||||
value: formatSummaryValue(dataIndex, maxVal),
|
||||
time: maxVal !== null ? getSummaryTime(dataIndex, 'max') : ''
|
||||
};
|
||||
rows[1].cells[dataIndex] = {
|
||||
value: formatSummaryValue(dataIndex, minVal),
|
||||
time: minVal !== null ? getSummaryTime(dataIndex, 'min') : ''
|
||||
};
|
||||
rows[2].cells[dataIndex] = {
|
||||
value: formatSummaryValue(dataIndex, avgVal),
|
||||
time: ''
|
||||
};
|
||||
});
|
||||
|
||||
return rows;
|
||||
});
|
||||
|
||||
return {
|
||||
// state
|
||||
selectedColumns,
|
||||
showSummaryCheckbox,
|
||||
showDeepCheckbox,
|
||||
isDataEmpty,
|
||||
// computed
|
||||
filteredCheckBoxOptions,
|
||||
isDeepMode,
|
||||
isSummaryMode,
|
||||
currentChartMode,
|
||||
currentColumns,
|
||||
tableScrollX,
|
||||
summaryColumns,
|
||||
summaryRows,
|
||||
// methods
|
||||
handleCheckboxChange
|
||||
};
|
||||
}
|
||||
@ -8,12 +8,30 @@
|
||||
<div class="search-form">
|
||||
<a-space size="middle">
|
||||
<div>所属基地:</div>
|
||||
<a-select v-model:value="searchData.baseId" placeholder="请选择所属基地" style="width: 200px" show-search
|
||||
:filter-option="filterOption" :options="jiDiList" @change="handleHydropowerStationChange" />
|
||||
<a-select
|
||||
v-model:value="searchData.baseId"
|
||||
placeholder="请选择所属基地"
|
||||
style="width: 200px"
|
||||
show-search
|
||||
:filter-option="filterOption"
|
||||
:options="jiDiList"
|
||||
@change="handleHydropowerStationChange"
|
||||
/>
|
||||
<div>所属栖息地:</div>
|
||||
<a-select v-model:value="searchData.fhstcd" placeholder=" " style="width: 200px" show-search
|
||||
:filter-option="filterOption" :options="stationOptions" />
|
||||
<a-input v-model:value="searchData.stnm" placeholder="请输入电站或设施名称" style="width: 200px" allow-clear />
|
||||
<a-select
|
||||
v-model:value="searchData.fhstcd"
|
||||
placeholder=" "
|
||||
style="width: 200px"
|
||||
show-search
|
||||
:filter-option="filterOption"
|
||||
:options="stationOptions"
|
||||
/>
|
||||
<a-input
|
||||
v-model:value="searchData.stnm"
|
||||
placeholder="请输入电站或设施名称"
|
||||
style="width: 200px"
|
||||
allow-clear
|
||||
/>
|
||||
|
||||
<a-button type="primary" @click="handleSearch">查询</a-button>
|
||||
<a-tooltip title="重置">
|
||||
@ -22,8 +40,16 @@
|
||||
</a-space>
|
||||
</div>
|
||||
<!-- 列表 -->
|
||||
<BasicTable ref="tableRef" :scrollY="360" :columns="columns" :list-url="fhGetKendoListCust" :enable-sort="true" @sort-change="handleSortChange"
|
||||
:search-params="searchParams" :transform-data="customTransform">
|
||||
<BasicTable
|
||||
ref="tableRef"
|
||||
:scrollY="360"
|
||||
:columns="columns"
|
||||
:list-url="fhGetKendoListCust"
|
||||
:enable-sort="true"
|
||||
@sort-change="handleSortChange"
|
||||
:search-params="searchParams"
|
||||
:transform-data="customTransform"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'ennm'">
|
||||
<a @click="handleViewDetail(record, 'dz')" class="text-link">
|
||||
@ -37,115 +63,96 @@
|
||||
</template>
|
||||
</template>
|
||||
</BasicTable>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch, onMounted,nextTick } from 'vue'
|
||||
import { msstbprptGetKendoList, fhGetKendoListCust } from '@/api/qxd'
|
||||
import BasicTable from '@/components/BasicTable/index.vue'
|
||||
import { useModelStore } from "@/store/modules/model";
|
||||
|
||||
import { ref, computed, watch, onMounted, nextTick } from 'vue';
|
||||
import { msstbprptGetKendoList, fhGetKendoListCust } from '@/api/qxd';
|
||||
import BasicTable from '@/components/BasicTable/index.vue';
|
||||
import { useModelStore } from '@/store/modules/model';
|
||||
|
||||
// ==================== Props 定义 ====================
|
||||
const props = defineProps<{
|
||||
baseId?: string
|
||||
tabs?: any[]
|
||||
activeKey?: string
|
||||
}>()
|
||||
baseId?: string;
|
||||
tabs?: any[];
|
||||
activeKey?: string;
|
||||
}>();
|
||||
|
||||
// ==================== 状态管理 ====================
|
||||
const tabIndex = ref(props.activeKey || 'FH')
|
||||
const tabIndex = ref(props.activeKey || 'FH');
|
||||
const searchData = ref<any>({
|
||||
baseId: props.baseId || 'all',
|
||||
fhstcd: 'all',
|
||||
stnm: null
|
||||
})
|
||||
});
|
||||
const modelStore = useModelStore();
|
||||
const tableRef = ref()
|
||||
const stationOptions: any = ref([])
|
||||
const tableRef = ref();
|
||||
const stationOptions: any = ref([]);
|
||||
|
||||
// ==================== 基地列表数据(硬编码) ====================
|
||||
const jiDiList: any = ref([
|
||||
{
|
||||
"value": "all",
|
||||
"label": "当前全部",
|
||||
|
||||
value: 'all',
|
||||
label: '当前全部'
|
||||
},
|
||||
{
|
||||
"value": "01",
|
||||
"label": "金沙江干流",
|
||||
|
||||
value: '01',
|
||||
label: '金沙江干流'
|
||||
},
|
||||
{
|
||||
"value": "02",
|
||||
"label": "雅砻江干流",
|
||||
|
||||
value: '02',
|
||||
label: '雅砻江干流'
|
||||
},
|
||||
{
|
||||
"value": "03",
|
||||
"label": "大渡河干流",
|
||||
|
||||
value: '03',
|
||||
label: '大渡河干流'
|
||||
},
|
||||
{
|
||||
"value": "04",
|
||||
"label": "乌江干流",
|
||||
|
||||
value: '04',
|
||||
label: '乌江干流'
|
||||
},
|
||||
{
|
||||
"value": "05",
|
||||
"label": "长江上游干流",
|
||||
|
||||
value: '05',
|
||||
label: '长江上游干流'
|
||||
},
|
||||
{
|
||||
"value": "10",
|
||||
"label": "湘西",
|
||||
|
||||
value: '10',
|
||||
label: '湘西'
|
||||
},
|
||||
{
|
||||
"value": "08",
|
||||
"label": "黄河上游干流",
|
||||
|
||||
value: '08',
|
||||
label: '黄河上游干流'
|
||||
},
|
||||
{
|
||||
"value": "09",
|
||||
"label": "黄河中游干流",
|
||||
|
||||
value: '09',
|
||||
label: '黄河中游干流'
|
||||
},
|
||||
{
|
||||
"value": "06",
|
||||
"label": "南盘江-红水河",
|
||||
|
||||
value: '06',
|
||||
label: '南盘江-红水河'
|
||||
},
|
||||
{
|
||||
"value": "12",
|
||||
"label": "东北",
|
||||
|
||||
value: '12',
|
||||
label: '东北'
|
||||
},
|
||||
{
|
||||
"value": "07",
|
||||
"label": "澜沧江干流",
|
||||
|
||||
value: '07',
|
||||
label: '澜沧江干流'
|
||||
},
|
||||
{
|
||||
"value": "13",
|
||||
"label": "怒江干流",
|
||||
|
||||
value: '13',
|
||||
label: '怒江干流'
|
||||
},
|
||||
{
|
||||
"value": "11",
|
||||
"label": "闽浙赣",
|
||||
|
||||
value: '11',
|
||||
label: '闽浙赣'
|
||||
},
|
||||
{
|
||||
"value": "other",
|
||||
"label": "其他",
|
||||
|
||||
value: 'other',
|
||||
label: '其他'
|
||||
}
|
||||
])
|
||||
]);
|
||||
// 表格列定义
|
||||
const columns = [
|
||||
{
|
||||
@ -153,77 +160,77 @@ const columns = [
|
||||
title: '设施名称',
|
||||
dataIndex: 'stnm',
|
||||
width: '176px',
|
||||
sorter: true,
|
||||
sorter: true
|
||||
},
|
||||
{
|
||||
key: 'baseName',
|
||||
title: '所在基地',
|
||||
dataIndex: 'baseName',
|
||||
width: '150px',
|
||||
sorter: true,
|
||||
sorter: true
|
||||
},
|
||||
{
|
||||
key: 'ennm',
|
||||
title: '所属电站',
|
||||
dataIndex: 'ennm',
|
||||
width: '150px',
|
||||
sorter: true,
|
||||
sorter: true
|
||||
},
|
||||
{
|
||||
key: 'fhstnm',
|
||||
title: '所属栖息地',
|
||||
dataIndex: 'fhstnm',
|
||||
width: '176px',
|
||||
sorter: true,
|
||||
sorter: true
|
||||
},
|
||||
{
|
||||
key: 'ststdt',
|
||||
title: '开工日期',
|
||||
dataIndex: 'ststdt',
|
||||
width: '150px',
|
||||
sorter: true,
|
||||
sorter: true
|
||||
},
|
||||
{
|
||||
key: 'esstdt',
|
||||
title: '建成日期',
|
||||
dataIndex: 'esstdt',
|
||||
width: '150px',
|
||||
sorter: true,
|
||||
sorter: true
|
||||
},
|
||||
{
|
||||
key: 'mway',
|
||||
title: '监测方式',
|
||||
dataIndex: 'mway',
|
||||
width: '150px',
|
||||
sorter: true,
|
||||
sorter: true
|
||||
},
|
||||
{
|
||||
key: 'vlsr',
|
||||
title: '数据接入来源',
|
||||
dataIndex: 'vlsr',
|
||||
width: '150px',
|
||||
sorter: true,
|
||||
sorter: true
|
||||
},
|
||||
{
|
||||
key: 'hydrodtin_type',
|
||||
title: '数据接入类型',
|
||||
dataIndex: 'hydrodtinType',
|
||||
width: '150px',
|
||||
sorter: true,
|
||||
sorter: true
|
||||
},
|
||||
{
|
||||
key: 'enable',
|
||||
title: '是否启用',
|
||||
dataIndex: 'enable',
|
||||
width: '150px',
|
||||
sorter: true,
|
||||
sorter: true
|
||||
},
|
||||
{
|
||||
key: 'dtin',
|
||||
title: '是否接入',
|
||||
dataIndex: 'dtin',
|
||||
width: '150px',
|
||||
sorter: true,
|
||||
sorter: true
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
@ -243,189 +250,196 @@ const handleSortChange = (info: { field: string; order: string | null }) => {
|
||||
sortState.value = null; // 恢复默认排序
|
||||
}
|
||||
nextTick(() => {
|
||||
handleSearch()
|
||||
handleSearch();
|
||||
});
|
||||
}
|
||||
};
|
||||
const searchParams = computed(() => {
|
||||
const params: any = { group: [],groupResultFlat: false,select:[] };
|
||||
const params: any = { group: [], groupResultFlat: false, select: [] };
|
||||
if (sortState.value) {
|
||||
// 转换为后端需要的格式,例如 [{ field: 'name', dir: 'asc' }]
|
||||
params.sort = [{
|
||||
params.sort = [
|
||||
{
|
||||
field: sortState.value.field,
|
||||
dir: sortState.value.order === 'ascend' ? 'asc' : 'desc'
|
||||
}];
|
||||
}else{
|
||||
params.sort = [{
|
||||
"field": "baseStepSort",
|
||||
"dir": "asc"
|
||||
}
|
||||
];
|
||||
} else {
|
||||
params.sort = [
|
||||
{
|
||||
field: 'baseStepSort',
|
||||
dir: 'asc'
|
||||
},
|
||||
{
|
||||
"field": "rvcdStepSort",
|
||||
"dir": "asc"
|
||||
field: 'rvcdStepSort',
|
||||
dir: 'asc'
|
||||
},
|
||||
{
|
||||
"field": "rstcdStepSort",
|
||||
"dir": "asc"
|
||||
}]
|
||||
field: 'rstcdStepSort',
|
||||
dir: 'asc'
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
return params;
|
||||
});
|
||||
const handleTabChange = (key: string) => {
|
||||
console.log('【Tab切换】', key)
|
||||
tabIndex.value = key
|
||||
handleSearch()
|
||||
}
|
||||
console.log('【Tab切换】', key);
|
||||
tabIndex.value = key;
|
||||
handleSearch();
|
||||
};
|
||||
const filterOption = (input: string, option: any) => {
|
||||
// 使用 options 属性时,option 是标准对象 { label, value }
|
||||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}
|
||||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||
};
|
||||
//所属基地发生变化
|
||||
const handleHydropowerStationChange = (value: string) => {
|
||||
console.log('【水电站选择变化】', value)
|
||||
console.log('【水电站选择变化】', value);
|
||||
// 清空测站选择
|
||||
searchData.value.fhstcd = 'all'
|
||||
getselectTwo()
|
||||
}
|
||||
searchData.value.fhstcd = 'all';
|
||||
getselectTwo();
|
||||
};
|
||||
//获取栖息地
|
||||
const getselectTwo = async () => {
|
||||
let params = {
|
||||
"filter": {
|
||||
"logic": "and",
|
||||
"filters": [
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
{
|
||||
"field": "sttpCode",
|
||||
"operator": "eq",
|
||||
"dataType": "string",
|
||||
"value": tabIndex.value
|
||||
field: 'sttpCode',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: tabIndex.value
|
||||
},
|
||||
searchData.value.baseId != 'all' ? {
|
||||
"field": "baseId",
|
||||
"operator": "eq",
|
||||
"dataType": "string",
|
||||
"value": searchData.value.baseId
|
||||
} : null
|
||||
searchData.value.baseId != 'all'
|
||||
? {
|
||||
field: 'baseId',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: searchData.value.baseId
|
||||
}
|
||||
: null
|
||||
].filter(Boolean)
|
||||
},
|
||||
"select": [
|
||||
"stcd",
|
||||
"stnm"
|
||||
]
|
||||
}
|
||||
let res = await msstbprptGetKendoList(params)
|
||||
console.log('【获取栖息地】', res)
|
||||
stationOptions.value = []
|
||||
select: ['stcd', 'stnm']
|
||||
};
|
||||
let res = await msstbprptGetKendoList(params);
|
||||
console.log('【获取栖息地】', res);
|
||||
stationOptions.value = [];
|
||||
if (res?.data?.data.length > 0) {
|
||||
stationOptions.value = res.data.data.map((item: any) => {
|
||||
return {
|
||||
label: item.stnm,
|
||||
value: item.stcd
|
||||
}
|
||||
})
|
||||
};
|
||||
});
|
||||
}
|
||||
stationOptions.value.unshift({
|
||||
label: '当前全部',
|
||||
value: 'all'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
const handleSearch = () => {
|
||||
console.log('【搜索】', searchData.value)
|
||||
console.log('【搜索】', searchData.value);
|
||||
const filters: any[] = [
|
||||
searchData.value.baseId != 'all' ? {
|
||||
"field": "baseId",
|
||||
"operator": "eq",
|
||||
"value": searchData.value.baseId
|
||||
} : null,
|
||||
searchData.value.fhstcd != 'all' ? {
|
||||
"field": "fhstcd",
|
||||
"operator": "eq",
|
||||
"value": searchData.value.fhstcd
|
||||
} : null,
|
||||
searchData.value.baseId != 'all'
|
||||
? {
|
||||
field: 'baseId',
|
||||
operator: 'eq',
|
||||
value: searchData.value.baseId
|
||||
}
|
||||
: null,
|
||||
searchData.value.fhstcd != 'all'
|
||||
? {
|
||||
field: 'fhstcd',
|
||||
operator: 'eq',
|
||||
value: searchData.value.fhstcd
|
||||
}
|
||||
: null,
|
||||
{
|
||||
"field": "sttpCode",
|
||||
"operator": "eq",
|
||||
"value": tabIndex.value
|
||||
field: 'sttpCode',
|
||||
operator: 'eq',
|
||||
value: tabIndex.value
|
||||
},
|
||||
searchData.value.stnm ? {
|
||||
"logic": "or",
|
||||
"filters": [
|
||||
searchData.value.stnm
|
||||
? {
|
||||
logic: 'or',
|
||||
filters: [
|
||||
{
|
||||
"field": "stnm",
|
||||
"operator": "contains",
|
||||
"value": searchData.value.stnm
|
||||
field: 'stnm',
|
||||
operator: 'contains',
|
||||
value: searchData.value.stnm
|
||||
},
|
||||
{
|
||||
"field": "ennm",
|
||||
"operator": "contains",
|
||||
"value": searchData.value.stnm
|
||||
field: 'ennm',
|
||||
operator: 'contains',
|
||||
value: searchData.value.stnm
|
||||
}
|
||||
]
|
||||
} : null
|
||||
].filter(Boolean)
|
||||
}
|
||||
: null
|
||||
].filter(Boolean);
|
||||
|
||||
const filter = {
|
||||
logic: 'and',
|
||||
filters
|
||||
}
|
||||
};
|
||||
// 刷新表格
|
||||
tableRef.value?.getList(filter)
|
||||
}
|
||||
tableRef.value?.getList(filter);
|
||||
};
|
||||
const handleReset = () => {
|
||||
console.log('【重置】')
|
||||
console.log('【重置】');
|
||||
searchData.value = {
|
||||
baseId: 'all',
|
||||
fhstcd: 'all',
|
||||
stnm: null
|
||||
}
|
||||
handleSearch()
|
||||
}
|
||||
};
|
||||
handleSearch();
|
||||
};
|
||||
// 自定义数据转换
|
||||
const customTransform = (res: any) => {
|
||||
return {
|
||||
records: res?.data?.data || [],
|
||||
total: res?.data?.total || 0
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
// 查看详情
|
||||
const handleViewDetail = (record: any, type: any) => {
|
||||
if (type == 'dz') {
|
||||
modelStore.modalVisible = true;
|
||||
modelStore.params.sttp = "ENG";
|
||||
modelStore.title = record.ennm + " 详情信息";
|
||||
modelStore.params.sttp = 'ENG';
|
||||
modelStore.title = record.ennm + ' 详情信息';
|
||||
modelStore.params.stcd = record.rstcd;
|
||||
} else {
|
||||
|
||||
if (tabIndex.value == 'FH') {
|
||||
modelStore.modalVisible = true;
|
||||
modelStore.params.sttp = "fh_point";
|
||||
modelStore.title = record.stnm + " 详情信息";
|
||||
modelStore.params.sttp = 'fh_point';
|
||||
modelStore.title = record.stnm + ' 详情信息';
|
||||
modelStore.params.stcd = record.stcd;
|
||||
modelStore.params.show = false
|
||||
modelStore.params.show = false;
|
||||
} else if (tabIndex.value == 'WTRV') {
|
||||
modelStore.modalVisible = true;
|
||||
modelStore.params.sttp = "wt_point";
|
||||
modelStore.title = record.stnm + " 详情信息";
|
||||
modelStore.params.sttp = 'wt_point';
|
||||
modelStore.title = record.stnm + ' 详情信息';
|
||||
modelStore.params.stcd = record.stcd;
|
||||
} else if (tabIndex.value == 'ZQ') {
|
||||
modelStore.modalVisible = true;
|
||||
modelStore.params.sttp = "fh_zq_point";
|
||||
modelStore.title = record.stnm + " 详情信息";
|
||||
modelStore.params.sttp = 'fh_zq_point';
|
||||
modelStore.title = record.stnm + ' 详情信息';
|
||||
modelStore.params.stcd = record.stcd;
|
||||
} else if (tabIndex.value == 'VD') {
|
||||
modelStore.modalVisible = true;
|
||||
modelStore.params.sttp = "stinfo_ai_video_point";
|
||||
modelStore.title = "视频监控站详情信息";
|
||||
modelStore.params.sttp = 'stinfo_ai_video_point';
|
||||
modelStore.title = '视频监控站详情信息';
|
||||
modelStore.isBasicEdit = true;
|
||||
modelStore.params.stcd = record.stcd;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
// ==================== 生命周期 ====================
|
||||
onMounted(() => {
|
||||
getselectTwo()
|
||||
handleSearch()
|
||||
})
|
||||
getselectTwo();
|
||||
handleSearch();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user