WholeProcessPlatform/frontend-sjgl/src/views/monitorData/SurfaceTemp/index.vue
2026-09-01 09:12:43 +08:00

372 lines
9.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

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

<template>
<div class="w-full h-full flex flex-col pt-[20px] pl-[20px] body_one">
<!-- 搜索组件 -->
<SurfaceTempSearch
@export-btn="exportBtn"
@search-finish="onSearchFinish"
@reset="onReset"
@seeEdit="handleSeeEdit"
@batch-delete="handleBatchDelete"
:show-batch-delete="currentSearchParams.timeScale === 'tm'"
:selected-count="selectedRowKeys.length"
:exportLoading="exportLoading"
ref="searchRef"
/>
<!-- 表格组件 -->
<BasicTable
ref="tableRef"
:enable-row-selection="currentSearchParams.timeScale === 'tm'"
:row-key="getRowKey"
:scrollX="tableScrollX"
:scrollY="tableScrollY"
:columns="Columns"
:list-url="currentListUrl"
:searchParams="{
sort: sort
}"
@selection-change="handleSelectionChange"
>
<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>
</BasicTable>
<EditSurfaceTempModal
v-model:open="editVisible"
:record="editRecord"
:time-scale="currentSearchParams.timeScale"
@success="handleEditSuccess"
/>
<DeleteConfirmModal
ref="deleteModalRef"
:delete-fn="handleDeleteFn"
title="删除表层水温数据"
label="数据"
@success="handleEditSuccess"
/>
<!-- 操作日志弹框 -->
<OperationLogModal
v-model:open="operationLogVisible"
:table-name="operationTableName"
:record-name-title="'断面名称'"
/>
</div>
</template>
<script setup lang="ts">
import { ref, computed, onMounted, nextTick } from 'vue';
import dayjs from 'dayjs';
import SurfaceTempSearch from './SurfaceTempSearch.vue';
import EditSurfaceTempModal from './EditSurfaceTempModal.vue';
import DeleteConfirmModal from '@/views/DataQueryMenuModule/components/conventionalHydropower/BasicData/DeleteConfirmModal.vue';
import OperationLogModal from '@/components/OperationLogModal/index.vue';
import BasicTable from '@/components/BasicTable/index.vue';
import { message } from 'ant-design-vue';
import {
getSurfaceTempList,
getSurfaceTempDayList,
getSurfaceTempMonthList,
deleteSurfaceTempInfo
} from '@/api/DataQueryMenuModule';
import { calcTableScrollY } from '@/utils/index';
import { buildTimeFilters } from '@/utils/buildTimeFilters';
const sort = computed(() => {
// 预定义排序数组
const sortMap = {
tm: [
{ field: 'baseStepSort', dir: 'asc' },
{ field: 'rvcd', dir: 'asc' },
{ field: 'rvcdStepSort', dir: 'asc' },
{ field: 'ennm', dir: 'asc' },
{ field: 'tm', dir: 'desc' }
],
dt: [
{ field: 'baseStepSort', dir: 'asc' },
{ field: 'rvcd', dir: 'asc' },
{ field: 'rvcdStepSort', dir: 'asc' },
{ field: 'stnm', dir: 'asc' },
{ field: 'dt', dir: 'desc' }
],
month: [
{ field: 'stnm', dir: 'desc' },
{ field: 'year', dir: 'desc' },
{ field: 'month', dir: 'desc' }
]
};
// 取值(若 timeScale 不在映射中,返回空数组)
return sortMap[currentSearchParams.value.timeScale] || [];
});
const tableRef = ref();
const searchRef = ref();
const tableScrollY = ref<string | number>(0);
const currentSearchParams = ref<any>({});
const exportLoading = ref(false);
const editVisible = ref(false);
const editRecord = ref<any>(null);
const deleteModalRef = ref();
const operationLogVisible = ref(false);
const operationTableName = 'SD_WTRV_R';
// 多选相关(唯一标识 stcd+tm日/月模式数据用 dt
const selectedRowKeys = ref<string[]>([]);
const selectedRows = ref<any[]>([]);
const getRowKey = (record: any) => `${record.stcd}_${record.tm ?? record.dt}`;
const handleSelectionChange = (keys: string[], rows: any[]) => {
selectedRowKeys.value = keys;
selectedRows.value = rows;
};
// 根据 timeScale 动态切换 API
const currentListUrl = computed(() => {
const timeScale = currentSearchParams.value.timeScale;
if (timeScale === 'dt') return getSurfaceTempDayList;
if (timeScale === 'month') return getSurfaceTempMonthList;
return getSurfaceTempList; // 默认 tm小时
});
const tableScrollX = computed(() =>
Math.max(
Columns.value.reduce(
(sum: number, col: any) => sum + (col.width || 180),
0
),
600
)
);
// 固定列(始终全部显示)
const allColumns: any[] = [
{
key: 'stnm',
title: '断面名称',
dataIndex: 'stnm',
visible: true,
sort: true,
ellipsis: true
},
{
key: 'wt',
title: '水温(℃)',
dataIndex: 'wt',
visible: true,
sort: true,
fixed: 'left',
customRender: ({ record }: any) => record.wt?.toFixed(1) || '-',
ellipsis: true
}
];
// 根据 timeScale 动态生成时间列
const timeColumn = computed(() => ({
key: 'tm',
title: () => {
const timeScale = currentSearchParams.value.timeScale;
if (timeScale === 'month') return '月';
if (timeScale === 'dt') return '时间';
return '时间';
},
dataIndex: 'tm',
visible: true,
sort: true,
ellipsis: true,
customRender: ({ record }: any) => {
const timeScale = currentSearchParams.value.timeScale;
if (timeScale === 'dt') {
return dayjs(record.dt).format('YYYY-MM-DD');
}
if (timeScale === 'month') {
const year = record.year ?? '-';
const month = record.month ?? '-';
return `${year}-${String(month).padStart(2, '0')}`;
}
return record.tm || '-';
}
}));
// 动态列(响应式)
const Columns = computed(() => {
const result = allColumns.map(col => ({ ...col }));
// 在基地列之后插入时间列
const baseIndex = result.findIndex(c => c.key === 'stnm');
result.splice(baseIndex + 1, 0, timeColumn.value);
if (currentSearchParams.value.timeScale === 'tm') {
result.push({
key: 'action',
title: '操作',
dataIndex: 'action',
fixed: 'right',
width: 120
});
}
return result;
});
const onSearchFinish = async (values: any) => {
currentSearchParams.value = values;
// 切换查询条件时清空选中
selectedRowKeys.value = [];
selectedRows.value = [];
tableRef.value?.clearSelection();
// 等待 prop 更新后再调用 getList
await nextTick();
initTable(values);
};
const onReset = async (values: any) => {
currentSearchParams.value = values;
// 切换查询条件时清空选中
selectedRowKeys.value = [];
selectedRows.value = [];
tableRef.value?.clearSelection();
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;
});
};
const handleEdit = (record: any) => {
editRecord.value = { ...record };
editVisible.value = true;
};
// 删除兼容单条record 本身批量record.records 数组)
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,
dt: r.tm
}));
return deleteSurfaceTempInfo({
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();
});
};
// 批量删除(仅小时 tm 模式,与单条删除一致)
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;
};
const handleEditSuccess = () => {
initTable(currentSearchParams.value);
};
const initTable = (values: any) => {
const filters = [
values.rvcd && values.rvcd !== 'all'
? {
field: 'rvcd',
operator: 'contains',
dataType: 'string',
value: values.rvcd
}
: null,
values.rstcd
? {
field: 'rstcd',
operator: 'eq',
dataType: 'string',
value: values.rstcd
}
: null,
values.stcd
? {
field: 'stcd',
operator: 'eq',
dataType: 'string',
value: values.stcd
}
: null,
...buildTimeFilters(values)
].filter(Boolean); // 移除空项
const params = {
logic: 'and',
filters
};
tableRef.value.getList(params);
};
onMounted(() => {
nextTick(() => {
tableScrollY.value = calcTableScrollY(tableRef.value);
});
});
</script>
<style scoped lang="scss">
.body_one {
position: relative;
z-index: 900;
pointer-events: all;
}
</style>