WholeProcessPlatform/frontend-sjgl/src/views/monitorData/FlowData/index.vue

623 lines
16 KiB
Vue
Raw Normal View History

2026-07-20 16:02:51 +08:00
<template>
2026-07-21 18:38:17 +08:00
<div class="w-full h-full flex flex-col pt-[20px] pl-[20px] body_one">
2026-07-20 16:02:51 +08:00
<!-- 搜索组件 -->
<FlowDataSearch
@export-btn="exportBtn"
@search-finish="onSearchFinish"
@reset="onReset"
@seeEdit="handleSeeEdit"
@batch-delete="handleBatchDelete"
:show-batch-delete="currentSearchParams.timeScale === 'tm'"
:selected-count="selectedRowKeys.length"
2026-07-20 16:02:51 +08:00
:exportLoading="exportLoading"
ref="searchRef"
/>
<!-- 表格组件 -->
<BasicTable
ref="tableRef"
:enable-row-selection="currentSearchParams.timeScale === 'tm'"
2026-07-20 16:02:51 +08:00
:scrollX="tableScrollX"
:scrollY="tableScrollY"
:columns="displayColumns"
:list-url="currentListUrl"
:searchParams="{
sort: sort
}"
@selection-change="handleSelectionChange"
2026-07-20 16:02:51 +08:00
>
<template #action="{ record }">
<template v-if="currentSearchParams.timeScale === 'tm'">
<a-button
type="link"
class="text-[#2f6b98]"
size="small"
@click="handleEdit(record)"
>编辑</a-button
>
<a-button
type="link"
danger
size="small"
@click="handleDelete(record)"
>删除</a-button
>
</template>
</template>
2026-07-20 16:02:51 +08:00
</BasicTable>
<!-- 编辑生态流量数据 Modal -->
<EditFlowDataModal
v-model:open="editVisible"
:record="editRecord"
@success="handleEditSuccess"
/>
<!-- 删除确认 Modal -->
<DeleteConfirmModal
ref="deleteModalRef"
:delete-fn="handleDeleteFn"
:label="deleteLabel"
:title="'删除' + deleteLabel"
@success="handleEditSuccess"
/>
<!-- 操作日志弹框 -->
<OperationLogModal
v-model:open="operationLogVisible"
:table-name="operationTableName"
/>
2026-07-20 16:02:51 +08:00
</div>
</template>
<script setup lang="ts">
import { ref, computed, onMounted, nextTick, h } from 'vue';
import dayjs from 'dayjs';
import FlowDataSearch from './FlowDataSearch.vue';
import EditFlowDataModal from './EditFlowDataModal.vue';
import DeleteConfirmModal from '@/views/conventionalHydropower/BasicData/DeleteConfirmModal.vue';
import OperationLogModal from '@/components/OperationLogModal/index.vue';
import { Tooltip, message } from 'ant-design-vue';
2026-07-20 16:02:51 +08:00
import BasicTable from '@/components/BasicTable/index.vue';
import {
getFlowDataList,
getFlowDataDayList,
getFlowDataMonthList,
deleteFlowDataInfo
2026-07-20 16:02:51 +08:00
} from '@/api/DataQueryMenuModule';
import { calcTableScrollY } from '@/utils/index';
import { buildTimeFilters } from '@/utils/buildTimeFilters';
const currentSearchParams = ref<any>({});
const sort = computed(() => {
return [
{ field: 'baseStepSort', dir: 'asc' },
{ field: 'rvcdStepSort', dir: 'asc' },
{ field: 'siteStepSort', dir: 'asc' },
currentSearchParams.value.timeScale == 'tm'
? { field: 'tm', dir: 'desc' }
: null,
currentSearchParams.value.timeScale == 'dt'
? { field: 'dt', dir: 'desc' }
: null,
currentSearchParams.value.timeScale == 'month'
? { field: 'year', dir: 'desc' }
: null,
currentSearchParams.value.timeScale == 'month'
? { field: 'month', dir: 'desc' }
: null
].filter(Boolean);
});
const tableRef = ref();
const searchRef = ref();
const tableScrollY = ref<string | number>(0);
const exportLoading = ref(false);
// 编辑/删除相关
const editVisible = ref(false);
const editRecord = ref<any>(null);
const deleteModalRef = ref();
const operationLogVisible = ref(false);
const deleteLabel = '生态流量数据';
// TODO: 操作日志表名待确认
const operationTableName = 'SD_QEC_R';
// 多选相关
const selectedRowKeys = ref<string[]>([]);
const selectedRows = ref<any[]>([]);
const handleSelectionChange = (keys: string[], rows: any[]) => {
selectedRowKeys.value = keys;
selectedRows.value = rows;
};
2026-07-20 16:02:51 +08:00
// 根据 timeScale 动态切换 API
const currentListUrl = computed(() => {
const timeScale = currentSearchParams.value.timeScale;
if (timeScale === 'dt') return getFlowDataDayList;
if (timeScale === 'month') return getFlowDataMonthList;
return getFlowDataList; // 默认 tm小时
});
const tableScrollX = computed(() =>
Math.max(
displayColumns.value.reduce(
(sum: number, col: any) => sum + (col.width || 180),
0
),
600
)
);
// 基础列(始终显示)
const baseColumns: any = [
{
key: 'stnm',
title: '电站名称',
dataIndex: 'stnm',
visible: true,
width: 150,
sort: true,
fixed: 'left',
ellipsis: true
},
{
key: 'baseName',
title: '基地',
dataIndex: 'baseName',
visible: true,
width: 150,
sort: true,
fixed: 'left',
ellipsis: true
},
{
key: 'tm',
title: '时间',
dataIndex: 'tm',
visible: true,
width: 150,
sort: true,
fixed: 'left',
ellipsis: true
},
{
key: 'qi',
title: '入库流量(m³/s)',
dataIndex: 'qi',
visible: true,
width: 150,
sort: true,
ellipsis: true,
customRender: ({ text }) => {
return text ? Number(text).toFixed(1) : '-';
}
},
{
key: 'qec',
title: '生态流量值(m³/s)',
dataIndex: 'qec',
visible: true,
sort: true,
width: 150,
ellipsis: true,
customRender: ({ text }) => {
return text ? Number(text).toFixed(1) : '-';
}
}
];
// 可控制显示的列
const ruleColumnsMap: any = {
'': [
// 全部 - 显示所有
{
key: 'qecLimit',
title: '生态环境部限值要求(m³/s)',
dataIndex: 'qecLimit',
visible: true,
sort: true,
width: 200,
ellipsis: true
},
{
key: 'sfdb',
// title: '生态流量是否达标',
dataIndex: 'sfdbName',
visible: true,
sort: true,
width: 170,
title: () =>
h('span', { style: 'display:flex;align-items:center;gap:4px' }, [
'生态流量是否达标',
h(
Tooltip,
{
title: h('ol', {}, [
h('li', {}, '达标判定规则:'),
h(
'li',
{},
'a)环评中对生态流量限值有明确要求的,按环评要求评判,'
),
h(
'li',
{},
'b)环评中未对生态流量限值有明确要求的,按水利部要求评判,'
),
h(
'li',
{},
'c)无环评要求、无水利部要求的按多年平均流量的10%作为评判依据,'
),
h('li', {}, 'd)当来水不足时,生态流量不小于入库流量判定达标,')
])
},
{
default: () =>
h('i', {
class: 'iconfont icon-iconQuestion'
})
}
)
])
},
{
key: 'mwrLimit',
title: '水利部限值要求(m³/s)',
dataIndex: 'mwrLimit',
visible: true,
width: 180,
sort: true,
ellipsis: true
},
{
key: 'mwrSfdb',
dataIndex: 'mwrSfdbName',
visible: true,
sort: true,
width: 180,
title: () =>
h('span', { style: 'display:flex;align-items:center;gap:4px' }, [
'水利部要求是否达标',
h(
Tooltip,
{
title: h('ol', {}, [
h('li', {}, '达标判定规则:'),
h(
'li',
{},
'a)环评中对生态流量限值有明确要求的,按环评要求评判,'
),
h(
'li',
{},
'b)环评中未对生态流量限值有明确要求的,按水利部要求评判,'
),
h(
'li',
{},
'c)无环评要求、无水利部要求的按多年平均流量的10%作为评判依据,'
),
h('li', {}, 'd)当来水不足时,生态流量不小于入库流量判定达标,')
])
},
{
default: () =>
h('i', {
class: 'iconfont icon-iconQuestion'
})
}
)
])
},
{
key: 'avqLimit',
title: '多年平均流量(m³/s)',
dataIndex: 'avqLimit',
visible: true,
sort: true,
width: 160
},
{
key: 'avqSfdb',
dataIndex: 'avqSfdbName',
visible: true,
sort: true,
width: 230,
title: () =>
h('span', { style: 'display:flex;align-items:center;gap:4px' }, [
'多年平均流量*10%是否达标',
h(
Tooltip,
{
title: h('ol', {}, [
h('li', {}, '达标判定规则:'),
h(
'li',
{},
'a)环评中对生态流量限值有明确要求的,按环评要求评判,'
),
h(
'li',
{},
'b)环评中未对生态流量限值有明确要求的,按水利部要求评判,'
),
h(
'li',
{},
'c)无环评要求、无水利部要求的按多年平均流量的10%作为评判依据,'
),
h('li', {}, 'd)当来水不足时,生态流量不小于入库流量判定达标,')
])
},
{
default: () =>
h('i', {
class: 'iconfont icon-iconQuestion'
})
}
)
])
}
],
sfdb: [
// 环评要求
{
key: 'qecLimit',
title: '生态环境部限值要求(m³/s)',
dataIndex: 'qecLimit',
visible: true,
sort: true,
width: 200,
ellipsis: true
},
{
key: 'sfdb',
title: '生态流量是否达标',
dataIndex: 'sfdbName',
visible: true,
sort: true,
width: 150
}
],
mwrSfdb: [
// 水利部要求
{
key: 'mwrLimit',
title: '水利部限值要求(m³/s)',
dataIndex: 'mwrLimit',
visible: true,
width: 180,
sort: true,
ellipsis: true
},
{
key: 'mwrSfdb',
title: '水利部要求是否达标',
dataIndex: 'mwrSfdbName',
visible: true,
sort: true,
width: 150
}
],
avqSfdb: [
// 多年平均流量10%
{
key: 'avqLimit',
title: '多年平均流量(m³/s)',
dataIndex: 'avqLimit',
visible: true,
sort: true,
width: 150
},
{
key: 'avqSfdb',
title: '多年平均流量*10%是否达标',
dataIndex: 'avqSfdbName',
visible: true,
sort: true,
width: 200
}
],
wstllyq: [] // 无生态流量要求 - 不显示
};
// 根据 ruleType 动态计算列
const displayColumns = computed(() => {
const ruleType = currentSearchParams.value.ruleType ?? '';
const ruleColumns = ruleColumnsMap[ruleType] || ruleColumnsMap[''];
const columns: any[] = [...baseColumns, ...ruleColumns];
// 仅 timeScale === 'tm' 时显示操作列
if (currentSearchParams.value.timeScale === 'tm') {
columns.push({
key: 'action',
title: '操作',
dataIndex: 'action',
fixed: 'right',
width: 120
});
}
return columns;
2026-07-20 16:02:51 +08:00
});
const onSearchFinish = async (values: any) => {
currentSearchParams.value = values;
// 切换查询条件时清空选中
selectedRowKeys.value = [];
selectedRows.value = [];
tableRef.value?.clearSelection();
2026-07-20 16:02:51 +08:00
await nextTick();
initTable(values);
};
const onReset = async (values: any) => {
currentSearchParams.value = values;
// 切换查询条件时清空选中
selectedRowKeys.value = [];
selectedRows.value = [];
tableRef.value?.clearSelection();
2026-07-20 16:02:51 +08:00
await nextTick();
initTable(values);
};
const exportBtn = () => {
if (exportLoading.value) return;
exportLoading.value = true;
searchRef.value.btnLoading = true;
tableRef.value
.exportTable({
fileName: `生态流量运行数据_${dayjs().format('YYYY-MM-DD HH-mm-ss')}`
})
.finally(() => {
exportLoading.value = false;
searchRef.value.btnLoading = false;
});
};
// 构建 ruleType 过滤条件
const buildRuleTypeFilters = (ruleType: string) => {
// 全部:不传
if (ruleType === '' || ruleType === undefined) return [];
// 环评要求
if (ruleType === 'sfdb') {
return [{ field: 'sfdb', operator: 'neq', dataType: 'string', value: '3' }];
}
// 水利部要求
if (ruleType === 'mwrSfdb') {
return [
{ field: 'mwrSfdb', operator: 'neq', dataType: 'string', value: '3' }
];
}
// 多年平均流量10%
if (ruleType === 'avqSfdb') {
return [
{ field: 'avqSfdb', operator: 'neq', dataType: 'string', value: '3' }
];
}
// 无生态流量要求:三个都不达标
if (ruleType === 'wstllyq') {
return [
{ field: 'sfdb', operator: 'eq', dataType: 'string', value: '3' },
{ field: 'mwrSfdb', operator: 'eq', dataType: 'string', value: '3' },
{ field: 'avqSfdb', operator: 'eq', dataType: 'string', value: '3' }
];
}
return [];
};
const initTable = (values: any) => {
const filters = [
values.rvcd && values.rvcd !== 'all'
? {
field: 'rvcd',
operator: 'contains',
dataType: 'string',
value: values.rvcd
}
: null,
values.rstcd
? {
2026-08-04 09:01:23 +08:00
field: 'stcd',
2026-07-20 16:02:51 +08:00
operator: 'eq',
dataType: 'string',
value: values.rstcd
}
: null,
...buildRuleTypeFilters(values.ruleType),
...buildTimeFilters(values)
].filter(Boolean);
const params = {
logic: 'and',
filters
};
tableRef.value.getList(params);
};
// 编辑
const handleEdit = (record: any) => {
editRecord.value = { ...record };
editVisible.value = true;
};
// 编辑成功回调
const handleEditSuccess = () => {
initTable(currentSearchParams.value);
};
// 删除兼容单条record 本身批量record.records 数组),仅小时(tm)数据支持删除
const handleDeleteFn = async (record: any, reason: string) => {
const list = Array.isArray(record.records) ? record.records : [record];
const dataList = list.map((r: any) => ({
id: r.stcd,
tm: r.tm
}));
return deleteFlowDataInfo({
dataList,
dataType: 'TIME',
source: reason
});
};
// 删除后刷新:清空选中(让批量删除按钮回到禁用状态)并重新加载列表
const refreshAfterDelete = () => {
selectedRowKeys.value = [];
selectedRows.value = [];
tableRef.value?.clearSelection();
initTable(currentSearchParams.value);
};
const handleDelete = (record: any) => {
deleteModalRef.value?.open(record, () => {
refreshAfterDelete();
});
};
// 批量删除
const handleBatchDelete = () => {
if (currentSearchParams.value.timeScale !== 'tm') {
message.info('仅小时数据支持删除');
return;
}
if (selectedRowKeys.value.length === 0) {
message.info('请先勾选要删除的数据');
return;
}
deleteModalRef.value?.open(
{
records: [...selectedRows.value],
stnm: `选中的 ${selectedRowKeys.value.length} 条数据`
},
() => {
refreshAfterDelete();
}
);
};
// 查看修改(操作日志)
const handleSeeEdit = () => {
operationLogVisible.value = true;
};
2026-07-20 16:02:51 +08:00
onMounted(() => {
nextTick(() => {
tableScrollY.value = calcTableScrollY();
});
});
</script>
2026-07-21 18:38:17 +08:00
<style scoped lang="scss">
.body_one {
position: relative;
z-index: 900;
pointer-events: all;
}
</style>