新框架bug修改
This commit is contained in:
parent
f42a10f8b1
commit
a267eb9cfd
@ -35,7 +35,7 @@ export function postIdUrl(data: any) {
|
||||
// 查询站点建设状态
|
||||
export function getBuildState(data: any) {
|
||||
return request({
|
||||
url: '/wt/vmsstbprpt/GetKendoList',
|
||||
url: '/overview/vmsstbprpt/GetKendoList',
|
||||
method: 'post',
|
||||
data: {
|
||||
filter: data.filter,
|
||||
|
||||
@ -588,8 +588,7 @@ const createMergeCellHandler = (col: any) => {
|
||||
};
|
||||
|
||||
// --- 列配置增强(超出隐藏 + Tooltip + 插槽兼容 + 行合并 + 排序)---
|
||||
const enhancedColumns = computed(() => {
|
||||
return props.columns.map(col => {
|
||||
const processColumn = (col: any): any => {
|
||||
const enhancedCol: any = { ...col };
|
||||
|
||||
// 处理 sort 或 sorter: true
|
||||
@ -602,6 +601,13 @@ const enhancedColumns = computed(() => {
|
||||
: false;
|
||||
}
|
||||
|
||||
// 递归处理 children 列
|
||||
if (enhancedCol.children && enhancedCol.children.length > 0) {
|
||||
enhancedCol.children = enhancedCol.children.map((child: any) =>
|
||||
processColumn(child)
|
||||
);
|
||||
}
|
||||
|
||||
// 处理 merge 配置
|
||||
if (col.merge && col.dataIndex) {
|
||||
const baseCol = {
|
||||
@ -705,7 +711,10 @@ const enhancedColumns = computed(() => {
|
||||
...enhancedCol,
|
||||
ellipsis: true
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const enhancedColumns = computed(() => {
|
||||
return props.columns.map(col => processColumn(col));
|
||||
});
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
|
||||
@ -134,37 +134,44 @@ const columnsMap: Record<string, any[]> = {
|
||||
{
|
||||
title: '调查鱼类',
|
||||
dataIndex: 'tm',
|
||||
width: 160
|
||||
width: 160,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '调查批次',
|
||||
dataIndex: 'dcpc',
|
||||
width: 160
|
||||
width: 160,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '渔获物种类',
|
||||
dataIndex: 'name',
|
||||
width: 160
|
||||
width: 160,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '鱼类规格',
|
||||
dataIndex: 'fsz',
|
||||
width: 140
|
||||
width: 140,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '渔获物数量(尾)',
|
||||
dataIndex: 'fcnt',
|
||||
width: 140
|
||||
width: 140,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '性腺发育期',
|
||||
dataIndex: 'st',
|
||||
width: 140
|
||||
width: 140,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '早期资源量和种类',
|
||||
dataIndex: 'ps',
|
||||
width: 220
|
||||
width: 220,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '现场影像',
|
||||
@ -177,46 +184,54 @@ const columnsMap: Record<string, any[]> = {
|
||||
{
|
||||
title: '时间',
|
||||
dataIndex: 'tm',
|
||||
width: 220
|
||||
width: 220,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '水温(℃)',
|
||||
dataIndex: 'wt',
|
||||
width: 160
|
||||
width: 160,
|
||||
sort: true
|
||||
}
|
||||
],
|
||||
waterQuality: [
|
||||
{
|
||||
title: '时间',
|
||||
dataIndex: 'tm',
|
||||
width: 220
|
||||
width: 220,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: 'PH',
|
||||
dataIndex: 'ph',
|
||||
width: 140
|
||||
width: 140,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '溶解氧(mg/L)',
|
||||
dataIndex: 'dox',
|
||||
width: 180
|
||||
width: 180,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '电导率(μS/cm)',
|
||||
dataIndex: 'cond',
|
||||
width: 180
|
||||
width: 180,
|
||||
sort: true
|
||||
}
|
||||
],
|
||||
flowRate: [
|
||||
{
|
||||
title: '时间',
|
||||
dataIndex: 'tm',
|
||||
width: 220
|
||||
width: 220,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '流速(m/s)',
|
||||
dataIndex: 'flowrate',
|
||||
width: 160
|
||||
width: 160,
|
||||
sort: true
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@ -19,6 +19,10 @@
|
||||
sort: [{ field: 'yr', dir: 'desc' }]
|
||||
}"
|
||||
:list-url="getMonitorDataOnline"
|
||||
:paginationConfig="{
|
||||
showSizeChanger: false,
|
||||
showQuickJumper: false
|
||||
}"
|
||||
/>
|
||||
<!-- 图片预览弹框 -->
|
||||
<a-modal
|
||||
@ -95,23 +99,27 @@ const baseColumns = [
|
||||
title: '年份',
|
||||
dataIndex: 'yr',
|
||||
width: 120,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) =>
|
||||
text && text !== '-' ? dayjs(text).format('YYYY') : '-'
|
||||
},
|
||||
{
|
||||
title: '鱼种类',
|
||||
dataIndex: 'ftp',
|
||||
width: 100
|
||||
width: 100,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '鱼类规格(cm)',
|
||||
dataIndex: 'fsz',
|
||||
width: 100
|
||||
width: 100,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '过鱼数量(尾)',
|
||||
dataIndex: 'fcnt',
|
||||
width: 100
|
||||
width: 100,
|
||||
sort: true
|
||||
}
|
||||
];
|
||||
|
||||
@ -121,44 +129,52 @@ const detailColumns = [
|
||||
title: '测站名称',
|
||||
dataIndex: 'stnm',
|
||||
width: 240,
|
||||
fixed: 'left'
|
||||
fixed: 'left',
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '时间',
|
||||
dataIndex: 'tm',
|
||||
width: 120,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) =>
|
||||
text && text !== '-' ? dayjs(text).format('YYYY-MM-DD') : '-'
|
||||
},
|
||||
{
|
||||
title: '鱼种类',
|
||||
dataIndex: 'ftpName',
|
||||
width: 100
|
||||
width: 100,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '鱼长度(cm)',
|
||||
dataIndex: 'length',
|
||||
width: 100
|
||||
width: 100,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '鱼宽度(cm)',
|
||||
dataIndex: 'width',
|
||||
width: 100
|
||||
width: 100,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '鱼速度(m/s)',
|
||||
dataIndex: 'fishspeed',
|
||||
width: 100
|
||||
width: 100,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '鱼游向',
|
||||
dataIndex: 'directionName',
|
||||
width: 100
|
||||
width: 100,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '水温(℃)',
|
||||
dataIndex: 'temperature',
|
||||
width: 100,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) => {
|
||||
const num = parseFloat(text);
|
||||
return isNaN(num) ? '-' : num.toFixed(1);
|
||||
@ -168,6 +184,7 @@ const detailColumns = [
|
||||
title: '流速(m/s)',
|
||||
dataIndex: 'speed',
|
||||
width: 100,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) => {
|
||||
const num = parseFloat(text);
|
||||
return isNaN(num) ? '-' : num.toFixed(2);
|
||||
@ -178,6 +195,7 @@ const detailColumns = [
|
||||
dataIndex: 'firstimgurl',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) => {
|
||||
const hasValidUrl =
|
||||
text &&
|
||||
@ -209,6 +227,7 @@ const detailColumns = [
|
||||
dataIndex: 'videourl',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) => {
|
||||
const hasValidUrl =
|
||||
text &&
|
||||
|
||||
@ -31,12 +31,19 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="table-wrapper">
|
||||
<a-spin :spinning="tableLoading" tip="加载中...">
|
||||
<BasicTable
|
||||
:scrollY="480"
|
||||
:scrollX="tableScrollX"
|
||||
:columns="tableColumns"
|
||||
:data="tableData"
|
||||
:paginationConfig="{
|
||||
showSizeChanger: false,
|
||||
showQuickJumper: false
|
||||
}"
|
||||
@sort-change="handleSortChange"
|
||||
/>
|
||||
</a-spin>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -80,6 +87,8 @@ import { useModelStore } from '@/store/modules/model';
|
||||
import BasicTable from '@/components/BasicTable/index.vue';
|
||||
import { DateSetting } from '@/utils/enumeration';
|
||||
import { useDraggable } from '@/utils/drag';
|
||||
import { useServerSortTableData } from '@/hooks/useServerSortTableData';
|
||||
import type { SortField } from '@/hooks/useServerSortTableData';
|
||||
|
||||
const modelStore = useModelStore();
|
||||
|
||||
@ -94,7 +103,6 @@ const isQxdMode = computed(() => props.code === 'qxd.tabs.lcjs');
|
||||
|
||||
const hasLoaded = ref(false);
|
||||
const isLoading = ref(false);
|
||||
const tableData = ref<any[]>([]);
|
||||
const chartData = ref<any[]>([]);
|
||||
const chartRef = ref<HTMLElement>();
|
||||
let chartInstance: echarts.ECharts | null = null;
|
||||
@ -122,6 +130,36 @@ const initDateRange = (): [Dayjs, Dayjs] => {
|
||||
};
|
||||
const dateRange = ref<[Dayjs, Dayjs] | undefined>(initDateRange());
|
||||
|
||||
// ==================== 表格排序 ====================
|
||||
const buildSearchParams = (sort?: SortField) => {
|
||||
const currentStcd = isQxdMode.value ? props.stcd : modelStore.params.stcd;
|
||||
if (!dateRange.value || !currentStcd) return null;
|
||||
return {
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
{ field: 'stcd', operator: 'eq', dataType: 'string', value: currentStcd },
|
||||
{ field: 'tm', operator: 'gte', dataType: 'date', 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') }
|
||||
]
|
||||
},
|
||||
sort: sort ? [sort] : [{ field: 'tm', dir: 'asc' }]
|
||||
};
|
||||
};
|
||||
|
||||
const requestData = async (params: any) => {
|
||||
if (isQxdMode.value) {
|
||||
const { getMonitorDataZq } = await import('@/api/mapModal');
|
||||
return await getMonitorDataZq(params);
|
||||
}
|
||||
return await queryPostUrlList(props.url, params);
|
||||
};
|
||||
|
||||
const { tableData, isLoading: tableLoading, handleSortChange } = useServerSortTableData<any>({
|
||||
request: requestData,
|
||||
buildSearchParams
|
||||
});
|
||||
|
||||
// 表格列配置
|
||||
const tableColumns = [
|
||||
{
|
||||
@ -129,6 +167,7 @@ const tableColumns = [
|
||||
dataIndex: 'tm',
|
||||
width: 180,
|
||||
fixed: 'left',
|
||||
sort: true,
|
||||
customRender: ({ text }: any) =>
|
||||
text ? dayjs(text).format('YYYY-MM-DD HH:mm:ss') : '-'
|
||||
},
|
||||
@ -136,6 +175,7 @@ const tableColumns = [
|
||||
title: '水位(m)',
|
||||
dataIndex: 'z',
|
||||
width: 120,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text).toFixed(2) : '-'
|
||||
},
|
||||
@ -143,6 +183,7 @@ const tableColumns = [
|
||||
title: '流量(m³/s)',
|
||||
dataIndex: 'q',
|
||||
width: 130,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text).toFixed(1) : '-'
|
||||
},
|
||||
@ -150,6 +191,7 @@ const tableColumns = [
|
||||
title: '流速(m³/s)',
|
||||
dataIndex: 'v',
|
||||
width: 130,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text).toFixed(2) : '-'
|
||||
},
|
||||
@ -157,6 +199,7 @@ const tableColumns = [
|
||||
title: '水位视频',
|
||||
dataIndex: 'rzVideoPath',
|
||||
width: 120,
|
||||
sort: true,
|
||||
customRender: ({ record }: any) => {
|
||||
if (!record.rzVideoPath) return '-';
|
||||
return h(
|
||||
@ -174,6 +217,7 @@ const tableColumns = [
|
||||
title: '流速视频',
|
||||
dataIndex: 'speedVideoPath',
|
||||
width: 120,
|
||||
sort: true,
|
||||
customRender: ({ record }: any) => {
|
||||
if (!record.speedVideoPath) return '-';
|
||||
return h(
|
||||
@ -405,7 +449,8 @@ const updateChart = (data: any[]) => {
|
||||
|
||||
// 数据请求
|
||||
const fetchData = async () => {
|
||||
if (!dateRange.value) return;
|
||||
const params = buildSearchParams();
|
||||
if (!params) return;
|
||||
|
||||
// qxd模式必须有stcd才能请求
|
||||
if (isQxdMode.value && !props.stcd) {
|
||||
@ -415,48 +460,17 @@ const fetchData = async () => {
|
||||
isLoading.value = true;
|
||||
|
||||
try {
|
||||
// 确定使用的stcd:qxd模式使用props.stcd,否则使用modelStore.params.stcd
|
||||
const currentStcd = isQxdMode.value ? props.stcd : modelStore.params.stcd;
|
||||
|
||||
const filterParams = {
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
{
|
||||
field: 'stcd',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: currentStcd
|
||||
},
|
||||
{
|
||||
field: 'tm',
|
||||
operator: 'gte',
|
||||
dataType: 'date',
|
||||
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')
|
||||
}
|
||||
]
|
||||
},
|
||||
sort: [{ field: 'tm', dir: 'asc' }]
|
||||
};
|
||||
|
||||
// qxd模式使用getMonitorDataZq,非qxd模式使用queryPostUrlList
|
||||
let rawData;
|
||||
if (isQxdMode.value) {
|
||||
const { getMonitorDataZq } = await import('@/api/mapModal');
|
||||
const res = await getMonitorDataZq(filterParams);
|
||||
const res = await getMonitorDataZq(params);
|
||||
rawData = res?.data?.data || res?.data?.records || [];
|
||||
} else {
|
||||
const res = await queryPostUrlList(props.url, filterParams);
|
||||
const res = await queryPostUrlList(props.url, params);
|
||||
rawData = res?.data?.data || res?.data?.records || [];
|
||||
}
|
||||
|
||||
tableData.value = [...rawData].reverse();
|
||||
tableData.value = [...rawData];
|
||||
chartData.value = rawData;
|
||||
nextTick(() => updateChart(rawData));
|
||||
} catch (error) {
|
||||
|
||||
@ -31,12 +31,20 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="table-wrapper">
|
||||
<a-spin :spinning="tableLoading" tip="加载中...">
|
||||
<BasicTable
|
||||
ref="tableRef"
|
||||
:scrollY="480"
|
||||
:scrollX="tableScrollX"
|
||||
:columns="tableColumns"
|
||||
:data="tableData"
|
||||
:paginationConfig="{
|
||||
showSizeChanger: false,
|
||||
showQuickJumper: false
|
||||
}"
|
||||
@sort-change="handleSortChange"
|
||||
/>
|
||||
</a-spin>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -52,6 +60,8 @@ import { getMonitorData } from '@/api/mapModal';
|
||||
import { useModelStore } from '@/store/modules/model';
|
||||
import BasicTable from '@/components/BasicTable/index.vue';
|
||||
import { DateSetting } from '@/utils/enumeration';
|
||||
import { useServerSortTableData } from '@/hooks/useServerSortTableData';
|
||||
import type { SortField } from '@/hooks/useServerSortTableData';
|
||||
|
||||
const modelStore = useModelStore();
|
||||
|
||||
@ -61,8 +71,8 @@ const props = defineProps({
|
||||
|
||||
const hasLoaded = ref(false);
|
||||
const isLoading = ref(false);
|
||||
const tableData = ref<any[]>([]);
|
||||
const chartData = ref<any[]>([]);
|
||||
const tableRef = ref<any>();
|
||||
|
||||
// ==================== 图表 ====================
|
||||
const chartRef = ref<HTMLElement>();
|
||||
@ -402,6 +412,28 @@ const initDateRange = (): [Dayjs, Dayjs] => {
|
||||
};
|
||||
const dateRange = ref<[Dayjs, Dayjs] | undefined>(initDateRange());
|
||||
|
||||
// ==================== 表格排序 ====================
|
||||
const buildSearchParams = (sort?: SortField) => {
|
||||
const stcd = modelStore.params.stcd;
|
||||
if (!dateRange.value || !stcd) return null;
|
||||
return {
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
{ field: 'stcd', operator: 'eq', dataType: 'string', value: stcd },
|
||||
{ field: 'tm', operator: 'gte', dataType: 'date', 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') }
|
||||
]
|
||||
},
|
||||
sort: sort ? [sort] : [{ field: 'tm', dir: 'asc' }]
|
||||
};
|
||||
};
|
||||
|
||||
const { tableData, isLoading: tableLoading, handleSortChange } = useServerSortTableData<any>({
|
||||
request: getMonitorData,
|
||||
buildSearchParams
|
||||
});
|
||||
|
||||
// 空值兜底:null/undefined/空串/'-'占位符/NaN 均显示为 '-'
|
||||
const formatCell = (
|
||||
text: any,
|
||||
@ -422,6 +454,7 @@ const tableColumns = [
|
||||
dataIndex: 'tm',
|
||||
width: 150,
|
||||
fixed: 'left',
|
||||
sort: true,
|
||||
customRender: ({ text }: any) =>
|
||||
text && text !== '-' ? dayjs(text).format('YYYY-MM-DD HH:mm:ss') : '-'
|
||||
},
|
||||
@ -429,18 +462,21 @@ const tableColumns = [
|
||||
title: '坝上水位(m)',
|
||||
dataIndex: 'rz',
|
||||
width: 100,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) => formatCell(text, v => v.toFixed(2))
|
||||
},
|
||||
{
|
||||
title: '坝下水位(m)',
|
||||
dataIndex: 'dz',
|
||||
width: 100,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) => formatCell(text, v => v.toFixed(2))
|
||||
},
|
||||
{
|
||||
title: '入库流量(m³/s)',
|
||||
dataIndex: 'qi',
|
||||
width: 120,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) =>
|
||||
formatCell(text, v => String(Math.round(v)))
|
||||
},
|
||||
@ -448,18 +484,21 @@ const tableColumns = [
|
||||
title: '出库流量(m³/s)',
|
||||
dataIndex: 'qo',
|
||||
width: 120,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) => formatCell(text, v => String(v))
|
||||
},
|
||||
{
|
||||
title: '生态流量(m³/s)',
|
||||
dataIndex: 'qec',
|
||||
width: 120,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) => formatCell(text, v => v.toFixed(1))
|
||||
},
|
||||
{
|
||||
title: '生态流量限值(m³/s)',
|
||||
dataIndex: 'qecLimit',
|
||||
width: 140,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) => formatCell(text, v => v.toFixed(1))
|
||||
}
|
||||
];
|
||||
@ -467,42 +506,16 @@ const tableScrollX = tableColumns.reduce((s, c) => s + (c.width || 100), 0);
|
||||
|
||||
// 数据请求
|
||||
const fetchData = async () => {
|
||||
if (!dateRange.value) return;
|
||||
const params = buildSearchParams();
|
||||
if (!params) return;
|
||||
isLoading.value = true;
|
||||
|
||||
try {
|
||||
const filterParams = {
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
{
|
||||
field: 'stcd',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: modelStore.params.stcd
|
||||
},
|
||||
{
|
||||
field: 'tm',
|
||||
operator: 'gte',
|
||||
dataType: 'date',
|
||||
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')
|
||||
}
|
||||
]
|
||||
},
|
||||
sort: [{ field: 'tm', dir: 'asc' }]
|
||||
};
|
||||
|
||||
const res = await getMonitorData(filterParams);
|
||||
const res = await getMonitorData(params);
|
||||
const rawData = res?.data?.data || res?.data?.records || [];
|
||||
|
||||
tableData.value = [...rawData].reverse();
|
||||
chartData.value = rawData;
|
||||
tableData.value = [...rawData];
|
||||
} catch (error) {
|
||||
console.error('获取数据失败:', error);
|
||||
tableData.value = [];
|
||||
|
||||
@ -82,7 +82,8 @@ const tableColumns = ref([
|
||||
{
|
||||
title: '救助数量(只)',
|
||||
dataIndex: 'tecnt',
|
||||
width: 180
|
||||
width: 180,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '放生地点',
|
||||
|
||||
@ -105,6 +105,7 @@ const tableColumns = ref([
|
||||
title: '计划养殖规模(万尾)',
|
||||
dataIndex: 'fcntjh',
|
||||
width: 150,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) => {
|
||||
if (text == null || text === '-') return '-';
|
||||
return (Number(text) / 10000).toFixed(4);
|
||||
@ -114,6 +115,7 @@ const tableColumns = ref([
|
||||
title: '实际完成数量(万尾)',
|
||||
dataIndex: 'fcntjc',
|
||||
width: 150,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) => {
|
||||
if (text == null || text === '-') return '-';
|
||||
return (Number(text) / 10000).toFixed(4);
|
||||
@ -160,6 +162,7 @@ const tableColumns = ref([
|
||||
title: '全长(cm)',
|
||||
dataIndex: 'fsz',
|
||||
width: 150,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) => {
|
||||
return formatRangeOrDecimal(text, 2);
|
||||
}
|
||||
@ -168,6 +171,7 @@ const tableColumns = ref([
|
||||
title: '体重(kg)',
|
||||
dataIndex: 'fwet',
|
||||
width: 150,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) => {
|
||||
return text == null || text === '-' ? '-' : text;
|
||||
}
|
||||
|
||||
@ -136,6 +136,7 @@ const tableColumns = ref([
|
||||
title: '存活率(%)',
|
||||
dataIndex: 'rate',
|
||||
width: 120,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) => {
|
||||
if (
|
||||
text === undefined ||
|
||||
|
||||
@ -228,6 +228,7 @@ const normalizeColumns = (columns: any[] = []): any[] =>
|
||||
key: column.key || column.dataIndex || column.title,
|
||||
width: column.width,
|
||||
fixed: column.fixed || undefined,
|
||||
sort: column.sort === true || undefined,
|
||||
customRender:
|
||||
column.dataType === 'date'
|
||||
? ({ text }: { text: unknown }) =>
|
||||
@ -574,7 +575,7 @@ const getTableList = async (params: any) => {
|
||||
current: params?.skip || 1,
|
||||
size: params?.take || DEFAULT_TABLE_PAGE_SIZE,
|
||||
filter: params?.filter,
|
||||
sort: [
|
||||
sort: params?.sort || [
|
||||
{
|
||||
field: 'tm',
|
||||
dir: 'desc'
|
||||
|
||||
@ -9,6 +9,7 @@ export const qinYuXinXi = [
|
||||
visible: true,
|
||||
fixed: '',
|
||||
ellipsis: true,
|
||||
sort: true,
|
||||
wrap: false,
|
||||
dictType: '',
|
||||
dictCode: '',
|
||||
@ -94,6 +95,7 @@ export const qinYuXinXi = [
|
||||
visible: true,
|
||||
fixed: '',
|
||||
ellipsis: true,
|
||||
sort: true,
|
||||
wrap: false,
|
||||
dictType: '',
|
||||
dictCode: '',
|
||||
@ -121,6 +123,7 @@ export const qinYuXinXi = [
|
||||
visible: true,
|
||||
fixed: '',
|
||||
ellipsis: true,
|
||||
sort: true,
|
||||
wrap: false,
|
||||
dictType: '',
|
||||
dictCode: '',
|
||||
@ -170,6 +173,7 @@ export const qinYuXinXi = [
|
||||
visible: true,
|
||||
fixed: '',
|
||||
ellipsis: true,
|
||||
sort: true,
|
||||
wrap: false,
|
||||
dictType: '',
|
||||
dictCode: '',
|
||||
@ -222,6 +226,7 @@ export const qinYuXinXi = [
|
||||
visible: true,
|
||||
fixed: '',
|
||||
ellipsis: true,
|
||||
sort: true,
|
||||
wrap: false,
|
||||
dictType: '',
|
||||
dictCode: '',
|
||||
@ -674,6 +679,7 @@ export const qinYuPeiYuFangShi = [
|
||||
visible: true,
|
||||
fixed: '',
|
||||
ellipsis: true,
|
||||
sort: true,
|
||||
wrap: false,
|
||||
dictType: '',
|
||||
dictCode: '',
|
||||
@ -1902,6 +1908,7 @@ export const taoTaiQinYu = [
|
||||
visible: true,
|
||||
fixed: '',
|
||||
ellipsis: true,
|
||||
sort: true,
|
||||
wrap: false,
|
||||
dictType: '',
|
||||
dictCode: '',
|
||||
@ -1934,6 +1941,7 @@ export const taoTaiQinYu = [
|
||||
visible: true,
|
||||
fixed: '',
|
||||
ellipsis: true,
|
||||
sort: true,
|
||||
wrap: false,
|
||||
dictType: '',
|
||||
dictCode: '',
|
||||
@ -1961,6 +1969,7 @@ export const taoTaiQinYu = [
|
||||
visible: true,
|
||||
fixed: '',
|
||||
ellipsis: true,
|
||||
sort: true,
|
||||
wrap: false,
|
||||
dictType: '',
|
||||
dictCode: '',
|
||||
|
||||
@ -49,13 +49,23 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="table-wrapper">
|
||||
<a-spin :spinning="tableLoading" tip="加载中...">
|
||||
<div class="text" v-if="modelStore.params.sttpCode == 'WQFB'">
|
||||
《渔业水质标准》(GB11607-89):非鲑科鱼类水域溶解氧限值为大于等于3,ph大于等于6.5且小于等于8.5。
|
||||
</div>
|
||||
<BasicTable
|
||||
ref="tableRef"
|
||||
:scrollY="480"
|
||||
:scrollX="tableScrollX"
|
||||
:columns="currentColumns"
|
||||
:data="tableData"
|
||||
:paginationConfig="{
|
||||
showSizeChanger: false,
|
||||
showQuickJumper: false
|
||||
}"
|
||||
@sort-change="handleSortChange"
|
||||
/>
|
||||
</a-spin>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -82,6 +92,8 @@ import {
|
||||
import { useModelStore } from '@/store/modules/model';
|
||||
import BasicTable from '@/components/BasicTable/index.vue';
|
||||
import { DateSetting } from '@/utils/enumeration';
|
||||
import { useServerSortTableData } from '@/hooks/useServerSortTableData';
|
||||
import type { SortField } from '@/hooks/useServerSortTableData';
|
||||
|
||||
const modelStore = useModelStore();
|
||||
const exportLoading = ref(false);
|
||||
@ -97,7 +109,6 @@ const isQxdMode = computed(() => props.code === 'qxd.tabs.szjc');
|
||||
|
||||
const hasLoaded = ref(false);
|
||||
const isLoading = ref(false);
|
||||
const tableData = ref<any[]>([]);
|
||||
const chartData = ref<any[]>([]);
|
||||
const chartRef = ref<HTMLElement>();
|
||||
let chartInstance: echarts.ECharts | null = null;
|
||||
@ -121,6 +132,47 @@ const initDateRange = (): [Dayjs, Dayjs] => {
|
||||
};
|
||||
const dateRange = ref<[Dayjs, Dayjs] | undefined>(initDateRange());
|
||||
|
||||
// ==================== 表格排序 ====================
|
||||
const buildSearchParams = (sort?: SortField) => {
|
||||
const currentStcd = isQxdMode.value ? props.stcd : modelStore.params.stcd;
|
||||
if (!dateRange.value || !currentStcd) return null;
|
||||
return {
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
{
|
||||
field: 'stcd',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: currentStcd
|
||||
},
|
||||
{
|
||||
field: 'tm',
|
||||
operator: 'gte',
|
||||
dataType: 'date',
|
||||
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')
|
||||
}
|
||||
]
|
||||
},
|
||||
sort: sort ? [sort] : [{ field: 'tm', dir: 'asc' }]
|
||||
};
|
||||
};
|
||||
|
||||
const {
|
||||
tableData,
|
||||
isLoading: tableLoading,
|
||||
handleSortChange
|
||||
} = useServerSortTableData<any>({
|
||||
request: getMonitorDataWaterQualityList,
|
||||
buildSearchParams
|
||||
});
|
||||
|
||||
// ==================== Checkbox 配置 ====================
|
||||
const selectedColumns = ref<any[]>([]);
|
||||
const checkBoxOptions = [{ label: '综合分析', value: 'summary' }];
|
||||
@ -176,6 +228,7 @@ const fixedColumns = [
|
||||
dataIndex: 'tm',
|
||||
fixed: 'left',
|
||||
width: 160,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) =>
|
||||
text ? dayjs(text).format('YYYY-MM-DD HH:mm') : '-'
|
||||
},
|
||||
@ -183,19 +236,22 @@ const fixedColumns = [
|
||||
title: '水质要求',
|
||||
dataIndex: 'wwqtgName',
|
||||
fixed: 'left',
|
||||
width: 100
|
||||
width: 100,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '水质等级',
|
||||
dataIndex: 'wqgrdName',
|
||||
fixed: 'left',
|
||||
width: 100
|
||||
width: 100,
|
||||
sort: true
|
||||
},
|
||||
{
|
||||
title: '是否达标',
|
||||
dataIndex: 'sfdb',
|
||||
fixed: 'left',
|
||||
width: 100,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) => {
|
||||
const isUnqualified = text == 0; // 0是不达标,1是达标
|
||||
return {
|
||||
@ -232,6 +288,7 @@ const fixedQualityColumns = computed(() => {
|
||||
dataIndex,
|
||||
enabled: isEnabled,
|
||||
width,
|
||||
sort: true,
|
||||
customRender: ({ text, record }: any) => {
|
||||
if (!isEnabled) return '-'; // enable=0 显示-
|
||||
if (text === undefined || text === null || text === '') return '-';
|
||||
@ -272,6 +329,7 @@ const fixedQualityColumns = computed(() => {
|
||||
title: '出库流量(m³/s)',
|
||||
dataIndex: 'qo',
|
||||
width: 140,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) => {
|
||||
if (text === undefined || text === null || text === '') return '-';
|
||||
const num = Number(text);
|
||||
@ -411,11 +469,13 @@ const updateChart = (data: any[], enabledParams: any[]) => {
|
||||
// nameGap: 30,
|
||||
type: 'value',
|
||||
position: 'left',
|
||||
// axisLine: { lineStyle: { color: visibleSeriesList[0].itemStyle.color } },
|
||||
axisLine: { show: true, onZero: false, lineStyle: { color: '#000000' } },
|
||||
axisTick: { show: true, lineStyle: { color: '#000000' } },
|
||||
axisLabel: { color: visibleSeriesList[0].itemStyle.color },
|
||||
scale: true,
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: { color: '#bfbfbf', type: 'solid' }
|
||||
lineStyle: { color: '#e5e5e5', type: 'solid' }
|
||||
}
|
||||
});
|
||||
// 给所有series设置yAxisIndex
|
||||
@ -426,11 +486,9 @@ const updateChart = (data: any[], enabledParams: any[]) => {
|
||||
if (visibleSeriesList.length >= 2) {
|
||||
yAxisConfig.push({
|
||||
name: visibleSeriesList[1].yAxisName,
|
||||
// nameLocation: 'middle',
|
||||
// nameGap: 35,
|
||||
type: 'value',
|
||||
position: 'right',
|
||||
// axisLine: { lineStyle: { color: visibleSeriesList[1].itemStyle.color } },
|
||||
axisLine: { show: true, onZero: false, lineStyle: { color: '#000000' } },
|
||||
axisTick: { show: true, lineStyle: { color: '#000000' } },
|
||||
axisLabel: { color: visibleSeriesList[1].itemStyle.color },
|
||||
scale: true,
|
||||
splitLine: { show: false }
|
||||
});
|
||||
@ -438,12 +496,130 @@ const updateChart = (data: any[], enabledParams: any[]) => {
|
||||
visibleSeriesList[1].yAxisIndex = 1;
|
||||
}
|
||||
|
||||
// 单个图例时计算限值
|
||||
let limitMax: number | null = null;
|
||||
let limitMin: number | null = null;
|
||||
let limitLabel = '';
|
||||
let limitUnit = '';
|
||||
let limitMaxLabel = '';
|
||||
let limitMinLabel = '';
|
||||
|
||||
if (visibleSeriesNames.value.length === 1 && sorted.length > 0) {
|
||||
const selectedName = visibleSeriesNames.value[0];
|
||||
const selectedParam = allDetailParams.value.find(
|
||||
(p: any) => p.ysShowName === selectedName
|
||||
);
|
||||
if (selectedParam) {
|
||||
const fieldUpper = selectedParam.ys.toUpperCase();
|
||||
const firstRecord = sorted[0];
|
||||
limitUnit = parseUnit(selectedParam.showControl);
|
||||
|
||||
if (Array.isArray(firstRecord.max)) {
|
||||
const maxItem = firstRecord.max.find(
|
||||
(m: any) => m[fieldUpper] !== undefined
|
||||
);
|
||||
if (maxItem) limitMax = maxItem[fieldUpper];
|
||||
}
|
||||
if (Array.isArray(firstRecord.min)) {
|
||||
const minItem = firstRecord.min.find(
|
||||
(m: any) => m[fieldUpper] !== undefined
|
||||
);
|
||||
if (minItem) limitMin = minItem[fieldUpper];
|
||||
}
|
||||
|
||||
let limitValue = '';
|
||||
|
||||
if (limitMax !== null && limitMin !== null) {
|
||||
limitLabel = limitUnit
|
||||
? `限值:${limitMin}~${limitMax} ${limitUnit}`
|
||||
: `限值:${limitMin}~${limitMax}`;
|
||||
limitValue = limitUnit
|
||||
? `${limitMin}~${limitMax} ${limitUnit}`
|
||||
: `${limitMin}~${limitMax}`;
|
||||
limitMaxLabel = `最大值:${limitMax}`;
|
||||
limitMinLabel = `最小值:${limitMin}`;
|
||||
} else if (limitMax !== null) {
|
||||
limitLabel = limitUnit
|
||||
? `限值:${limitMax} ${limitUnit}`
|
||||
: `限值:${limitMax}`;
|
||||
limitValue = limitUnit ? `${limitMax} ${limitUnit}` : `${limitMax}`;
|
||||
limitMaxLabel = `限值:${limitMax}`;
|
||||
} else if (limitMin !== null) {
|
||||
limitLabel = limitUnit
|
||||
? `限值:${limitMin} ${limitUnit}`
|
||||
: `限值:${limitMin}`;
|
||||
limitValue = limitUnit ? `${limitMin} ${limitUnit}` : `${limitMin}`;
|
||||
limitMinLabel = `限值:${limitMin}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 单个图例时给series添加markLine限值虚线
|
||||
if (
|
||||
visibleSeriesNames.value.length === 1 &&
|
||||
(limitMax !== null || limitMin !== null)
|
||||
) {
|
||||
const targetSeries = series.find(
|
||||
(s: any) => s.name === visibleSeriesNames.value[0]
|
||||
);
|
||||
if (targetSeries) {
|
||||
const markLineData: any[] = [];
|
||||
if (limitMax !== null) {
|
||||
markLineData.push({
|
||||
yAxis: limitMax,
|
||||
label: { formatter: limitMaxLabel, position: 'end' }
|
||||
});
|
||||
}
|
||||
if (limitMin !== null) {
|
||||
markLineData.push({
|
||||
yAxis: limitMin,
|
||||
label: { formatter: limitMinLabel, position: 'end' }
|
||||
});
|
||||
}
|
||||
targetSeries.markLine = {
|
||||
silent: true,
|
||||
symbol: 'none',
|
||||
lineStyle: { color: '#87CEEB', type: 'dashed', width: 1.5 },
|
||||
data: markLineData
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 限值超出数据范围时扩展y轴,确保虚线可见
|
||||
if (
|
||||
visibleSeriesList.length === 1 &&
|
||||
(limitMax !== null || limitMin !== null)
|
||||
) {
|
||||
const dataValues = visibleSeriesList[0].data.filter((v: any) => v != null);
|
||||
const dataMin = dataValues.length > 0 ? Math.min(...dataValues) : Infinity;
|
||||
const dataMax = dataValues.length > 0 ? Math.max(...dataValues) : -Infinity;
|
||||
let needAdjust = false;
|
||||
|
||||
if (limitMin !== null && limitMin < dataMin) {
|
||||
yAxisConfig[0].min = limitMin - 0.5;
|
||||
needAdjust = true;
|
||||
}
|
||||
if (limitMax !== null && limitMax > dataMax) {
|
||||
yAxisConfig[0].max = limitMax + 0.5;
|
||||
needAdjust = true;
|
||||
}
|
||||
if (needAdjust) {
|
||||
delete yAxisConfig[0].scale;
|
||||
}
|
||||
}
|
||||
|
||||
// 构建legend selected状态
|
||||
const legendSelected = legendData.reduce((acc: any, name) => {
|
||||
acc[name] = visibleSeriesNames.value.includes(name);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// 构建单位映射
|
||||
const unitMap = new Map<string, string>();
|
||||
allDetailParams.value.forEach((p: any) => {
|
||||
unitMap.set(p.ysShowName, parseUnit(p.showControl));
|
||||
});
|
||||
|
||||
const option: any = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
@ -459,8 +635,13 @@ const updateChart = (data: any[], enabledParams: any[]) => {
|
||||
let html = `<div style="font-size:16px;margin-bottom:8px;">${fullTime}</div>`;
|
||||
params.forEach((p: any) => {
|
||||
const v = p.value != null ? Number(p.value).toFixed(2) : '-';
|
||||
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:${p.color};margin-right:8px;"></span><span style="flex:1;font-size:14px;">${p.seriesName}: </span><span style="font-size:14px;min-width:60px;text-align:right;"><strong>${v}</strong></span></div>`;
|
||||
const unit = unitMap.get(p.seriesName) || '';
|
||||
const displayValue = unit ? `${v} ${unit}` : v;
|
||||
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:${p.color};margin-right:8px;"></span><span style="flex:1;font-size:14px;">${p.seriesName}: </span><span style="font-size:14px;min-width:60px;text-align:right;"><strong>${displayValue}</strong></span></div>`;
|
||||
});
|
||||
if (limitLabel) {
|
||||
html += `<div style="margin:0px 0px 2px 18px;padding-top:6px;font-size:14px;">${limitLabel}</div>`;
|
||||
}
|
||||
return html;
|
||||
}
|
||||
},
|
||||
@ -482,12 +663,12 @@ const updateChart = (data: any[], enabledParams: any[]) => {
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: xAxisData,
|
||||
axisLine: { lineStyle: { color: '#000000' } },
|
||||
axisLine: { show: true, onZero: false, lineStyle: { color: '#000000' } },
|
||||
axisTick: { show: false },
|
||||
axisLabel: axisLabelConfig,
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: { color: '#bfbfbf', type: 'solid' }
|
||||
lineStyle: { color: '#e5e5e5', type: 'solid' }
|
||||
}
|
||||
},
|
||||
yAxis: yAxisConfig.length === 1 ? yAxisConfig[0] : yAxisConfig,
|
||||
@ -540,7 +721,8 @@ const bindLegendEvent = () => {
|
||||
|
||||
// ==================== 数据请求 ====================
|
||||
const fetchData = async () => {
|
||||
if (!dateRange.value) return;
|
||||
const params = buildSearchParams();
|
||||
if (!params) return;
|
||||
|
||||
// qxd模式必须有stcd才能请求
|
||||
if (isQxdMode.value && !props.stcd) {
|
||||
@ -552,43 +734,16 @@ const fetchData = async () => {
|
||||
// 确定使用的stcd:qxd模式使用props.stcd,否则使用modelStore.params.stcd
|
||||
const currentStcd = isQxdMode.value ? props.stcd : modelStore.params.stcd;
|
||||
|
||||
const filterParams = {
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
{
|
||||
field: 'stcd',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: currentStcd
|
||||
},
|
||||
{
|
||||
field: 'tm',
|
||||
operator: 'gte',
|
||||
dataType: 'date',
|
||||
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')
|
||||
}
|
||||
]
|
||||
},
|
||||
sort: [{ field: 'tm', dir: 'asc' }]
|
||||
};
|
||||
|
||||
// 并发请求三个接口
|
||||
const [qualityRes, detailRes, listRes] = await Promise.all([
|
||||
getMonitorDataWaterQuality(filterParams),
|
||||
getMonitorDataWaterQuality(params),
|
||||
getMonitorDataWaterQualityDetail({
|
||||
stcd: currentStcd,
|
||||
tbCode: 'WQ_R',
|
||||
startTime: dateRange.value[0].format('YYYY-MM-DD HH:mm:ss'),
|
||||
endTime: dateRange.value[1].format('YYYY-MM-DD HH:mm:ss')
|
||||
}),
|
||||
getMonitorDataWaterQualityList(filterParams)
|
||||
getMonitorDataWaterQualityList(params)
|
||||
]);
|
||||
|
||||
// 判断是否显示综合分析(只有当data不为null且不为空数组时才显示)
|
||||
@ -606,7 +761,7 @@ const fetchData = async () => {
|
||||
// 获取列表数据
|
||||
const listData = listRes?.data?.data || listRes?.data?.records || [];
|
||||
|
||||
tableData.value = [...listData].reverse();
|
||||
tableData.value = [...listData];
|
||||
chartData.value = listData;
|
||||
nextTick(() => updateChart(listData, allDetailParams.value));
|
||||
} catch (error) {
|
||||
@ -788,4 +943,13 @@ onBeforeUnmount(() => {
|
||||
}
|
||||
}
|
||||
}
|
||||
.text {
|
||||
color: rgb(229, 85, 85);
|
||||
padding-bottom: 4px;
|
||||
font-size: 14px;
|
||||
font-variant: tabular-nums;
|
||||
line-height: 1.5715;
|
||||
list-style: none;
|
||||
font-feature-settings: 'tnum';
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -49,12 +49,19 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="table-wrapper">
|
||||
<a-spin :spinning="tableLoading" tip="加载中...">
|
||||
|
||||
<BasicTable
|
||||
ref="tableRef"
|
||||
:scrollY="360"
|
||||
:scrollX="tableScrollX"
|
||||
:columns="currentColumns"
|
||||
:data="tableData"
|
||||
:paginationConfig="{
|
||||
showSizeChanger: false,
|
||||
showQuickJumper: false
|
||||
}"
|
||||
@sort-change="handleSortChange"
|
||||
>
|
||||
<template #summary>
|
||||
<a-table-summary fixed>
|
||||
@ -87,6 +94,7 @@
|
||||
</a-table-summary>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</a-spin>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -116,6 +124,8 @@ 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 { useServerSortTableData } from '@/hooks/useServerSortTableData';
|
||||
import type { SortField } from '@/hooks/useServerSortTableData';
|
||||
|
||||
const modelStore = useModelStore();
|
||||
|
||||
@ -127,7 +137,6 @@ const props = defineProps({
|
||||
|
||||
const hasLoaded = ref(false);
|
||||
const isLoading = ref(false);
|
||||
const tableData = ref<any[]>([]);
|
||||
const chartData = ref<any[]>([]);
|
||||
const chartRef = ref<HTMLElement>();
|
||||
let chartInstance: echarts.ECharts | null = null;
|
||||
@ -153,6 +162,30 @@ const initDateRange = (): [Dayjs, Dayjs] => {
|
||||
};
|
||||
const dateRange = ref<[Dayjs, Dayjs] | undefined>(initDateRange());
|
||||
|
||||
// ==================== 表格排序 ====================
|
||||
const isQxdMode = computed(() => props.code === 'qxd.tabs.jcsj');
|
||||
|
||||
const buildSearchParams = (sort?: SortField) => {
|
||||
const currentStcd = isQxdMode.value ? props.stcd : modelStore.params.stcd;
|
||||
if (!dateRange.value || !currentStcd) return null;
|
||||
return {
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
{ field: 'stcd', operator: 'eq', dataType: 'string', value: currentStcd },
|
||||
{ field: 'tm', operator: 'gte', dataType: 'date', 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') }
|
||||
]
|
||||
},
|
||||
sort: sort ? [sort] : [{ field: 'tm', dir: 'asc' }]
|
||||
};
|
||||
};
|
||||
|
||||
const { tableData, isLoading: tableLoading, handleSortChange } = useServerSortTableData<any>({
|
||||
request: getMonitorDataWaterTemp,
|
||||
buildSearchParams
|
||||
});
|
||||
|
||||
// ==================== Checkbox 配置 ====================
|
||||
const selectedColumns = ref<any[]>([]);
|
||||
const checkBoxOptions = [
|
||||
@ -215,6 +248,7 @@ const baseWaterTempColumns = [
|
||||
title: '时间',
|
||||
dataIndex: 'tm',
|
||||
fixed: 'left',
|
||||
sort: true,
|
||||
customRender: ({ text }: any) =>
|
||||
text ? dayjs(text).format('YYYY-MM-DD HH:mm') : '-'
|
||||
},
|
||||
@ -222,6 +256,7 @@ const baseWaterTempColumns = [
|
||||
title: '水温(°C)',
|
||||
dataIndex: 'wt',
|
||||
summary: true,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text).toFixed(1) : '-'
|
||||
}
|
||||
@ -232,6 +267,7 @@ const deepModeExtraColumns = [
|
||||
title: '等温水深(m)',
|
||||
dataIndex: 'deep_wt',
|
||||
summary: true,
|
||||
sort: true,
|
||||
customRender: ({ record }: any) => {
|
||||
const val = record?.wtvtDataVo?.wthg;
|
||||
return val !== undefined && val !== null ? Number(val).toFixed(2) : '-';
|
||||
@ -241,6 +277,7 @@ const deepModeExtraColumns = [
|
||||
title: '垂向水温(℃)',
|
||||
dataIndex: 'vert_wt',
|
||||
summary: true,
|
||||
sort: true,
|
||||
customRender: ({ record }: any) => {
|
||||
const val = record?.wtvtDataVo?.vwt;
|
||||
return val !== undefined && val !== null ? Number(val).toFixed(1) : '-';
|
||||
@ -254,6 +291,7 @@ const summaryModeColumns = [
|
||||
dataIndex: 'tm',
|
||||
width: 130,
|
||||
fixed: 'left',
|
||||
sort: true,
|
||||
customRender: ({ text }: any) =>
|
||||
text ? dayjs(text).format('YYYY-MM-DD HH:mm') : '-'
|
||||
},
|
||||
@ -261,6 +299,7 @@ const summaryModeColumns = [
|
||||
title: '出库水温(℃)',
|
||||
dataIndex: 'wt',
|
||||
summary: true,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text).toFixed(1) : '-'
|
||||
},
|
||||
@ -268,6 +307,7 @@ const summaryModeColumns = [
|
||||
title: '入库水温(℃)',
|
||||
dataIndex: 'iwt_wt',
|
||||
summary: true,
|
||||
sort: true,
|
||||
customRender: ({ record }: any) =>
|
||||
record?.iwtDataVo?.wt !== undefined && record?.iwtDataVo?.wt !== null
|
||||
? Number(record.iwtDataVo.wt).toFixed(1)
|
||||
@ -277,6 +317,7 @@ const summaryModeColumns = [
|
||||
title: '天然水温(°C)',
|
||||
dataIndex: 'natureTmp',
|
||||
summary: true,
|
||||
sort: true,
|
||||
customRender: ({ text }: any) =>
|
||||
text !== undefined && text !== null ? Number(text).toFixed(1) : '-'
|
||||
},
|
||||
@ -285,6 +326,7 @@ const summaryModeColumns = [
|
||||
dataIndex: 'tmp_at',
|
||||
summary: true,
|
||||
width: 80,
|
||||
sort: true,
|
||||
customRender: ({ record }: any) =>
|
||||
record?.tmpDataVo?.at !== undefined && record?.tmpDataVo?.at !== null
|
||||
? Number(record.tmpDataVo.at).toFixed(1)
|
||||
@ -295,6 +337,7 @@ const summaryModeColumns = [
|
||||
dataIndex: 'hydropw_qo',
|
||||
summary: true,
|
||||
width: 120,
|
||||
sort: true,
|
||||
customRender: ({ record }: any) =>
|
||||
record?.hydropwDataVo?.qo !== undefined &&
|
||||
record?.hydropwDataVo?.qo !== null
|
||||
@ -306,6 +349,7 @@ const summaryModeColumns = [
|
||||
dataIndex: 'hydropw_qi',
|
||||
summary: true,
|
||||
width: 120,
|
||||
sort: true,
|
||||
customRender: ({ record }: any) =>
|
||||
record?.hydropwDataVo?.qi !== undefined &&
|
||||
record?.hydropwDataVo?.qi !== null
|
||||
@ -855,10 +899,9 @@ const updateChart = (data: any[]) => {
|
||||
};
|
||||
|
||||
// ==================== 数据请求 ====================
|
||||
const isQxdMode = computed(() => props.code === 'qxd.tabs.jcsj');
|
||||
|
||||
const fetchData = async () => {
|
||||
if (!dateRange.value) return;
|
||||
const params = buildSearchParams();
|
||||
if (!params) return;
|
||||
|
||||
// qxd模式必须有stcd才能请求
|
||||
if (isQxdMode.value && !props.stcd) {
|
||||
@ -867,52 +910,22 @@ const fetchData = async () => {
|
||||
|
||||
isLoading.value = true;
|
||||
try {
|
||||
// 确定使用的stcd:qxd模式使用props.stcd,否则使用modelStore.params.stcd
|
||||
const currentStcd = isQxdMode.value ? props.stcd : modelStore.params.stcd;
|
||||
|
||||
const filterParams = {
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [
|
||||
{
|
||||
field: 'stcd',
|
||||
operator: 'eq',
|
||||
dataType: 'string',
|
||||
value: currentStcd
|
||||
},
|
||||
{
|
||||
field: 'tm',
|
||||
operator: 'gte',
|
||||
dataType: 'date',
|
||||
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')
|
||||
}
|
||||
]
|
||||
},
|
||||
sort: [{ field: 'tm', dir: 'asc' }]
|
||||
};
|
||||
|
||||
// qxd模式只调用getMonitorDataWaterTemp
|
||||
if (isQxdMode.value) {
|
||||
const mainRes = await getMonitorDataWaterTemp(filterParams);
|
||||
const mainRes = await getMonitorDataWaterTemp(params);
|
||||
const mainData = mainRes?.data?.data || mainRes?.data?.records || [];
|
||||
showSummaryCheckbox.value = false;
|
||||
showDeepCheckbox.value = false;
|
||||
selectedColumns.value = [];
|
||||
tableData.value = [...mainData].reverse();
|
||||
tableData.value = [...mainData];
|
||||
chartData.value = mainData;
|
||||
nextTick(() => updateChart(mainData));
|
||||
} else {
|
||||
// 原有模式
|
||||
const [mainRes, powerStationRes, powerStationRes2] = await Promise.all([
|
||||
getMonitorDataWaterTemp(filterParams),
|
||||
getMonitorDataWaterTempPowerStation({ stcd: currentStcd }),
|
||||
getMonitorDataWaterTempPowerStation2({ stcd: currentStcd })
|
||||
getMonitorDataWaterTemp(params),
|
||||
getMonitorDataWaterTempPowerStation({ stcd: modelStore.params.stcd }),
|
||||
getMonitorDataWaterTempPowerStation2({ stcd: modelStore.params.stcd })
|
||||
]);
|
||||
|
||||
const mainData = mainRes?.data?.data || mainRes?.data?.records || [];
|
||||
@ -922,7 +935,7 @@ const fetchData = async () => {
|
||||
showDeepCheckbox.value =
|
||||
!!powerStationRes?.data?.hasRstcdWtvt && powerStation2Data !== null;
|
||||
|
||||
tableData.value = [...mainData].reverse();
|
||||
tableData.value = [...mainData];
|
||||
chartData.value = mainData;
|
||||
nextTick(() => updateChart(mainData));
|
||||
}
|
||||
@ -1029,6 +1042,7 @@ const handleResize = () => {
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('resize', handleResize);
|
||||
// console.log('modelStore',modelStore)
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
|
||||
@ -465,35 +465,7 @@ const checkWaterTempConfig = async (stcd: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 功能11: 电站建设状态过滤 (React: sttp == "ENG" && eqtp != "QEC")
|
||||
const checkBuildState = async (stcd: string) => {
|
||||
try {
|
||||
const res = await getBuildState({
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [{ field: 'stcd', operator: 'eq', value: stcd }]
|
||||
}
|
||||
});
|
||||
|
||||
const buid = res?.data?.[0]?.bldsttCcode;
|
||||
// 0 未建 1 在建 2 已建
|
||||
const zj = ['基础信息', '实时视频', '全景影像', '查看报告'];
|
||||
const wj = ['基础信息', '查看报告'];
|
||||
|
||||
if (res?.data?.length > 0) {
|
||||
const zJTabData = tabsConfig.value?.filter((item: any) =>
|
||||
zj.includes(item.name)
|
||||
);
|
||||
const wJTabData = tabsConfig.value?.filter((item: any) =>
|
||||
wj.includes(item.name)
|
||||
);
|
||||
tabsConfig.value =
|
||||
buid == 1 ? zJTabData : buid == 0 ? wJTabData : tabsConfig.value;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('建设状态检查失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// QGC 完整 Tab 过滤逻辑(与 React setQGCTabList 对齐)
|
||||
const setQGCTabList = async (_tabs: any, stcd: string) => {
|
||||
@ -505,11 +477,12 @@ const setQGCTabList = async (_tabs: any, stcd: string) => {
|
||||
const res = await getBuildState({
|
||||
filter: {
|
||||
logic: 'and',
|
||||
filters: [{ field: 'stcd', operator: 'eq', value: stcd }]
|
||||
filters: [{ dataType:'string',field: 'stcd', operator: 'eq', value: stcd }]
|
||||
}
|
||||
});
|
||||
|
||||
const buid = res?.data?.[0]?.bldsttCcode;
|
||||
const buid = res?.data?.data[0]?.bldsttCcode;
|
||||
// debugger
|
||||
const zj = ['基础信息', '实时视频', '全景影像', '查看报告'];
|
||||
const wj = ['基础信息', '查看报告'];
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user