414 lines
9.1 KiB
Vue
414 lines
9.1 KiB
Vue
<template>
|
||
<div class="year-average-container">
|
||
<!-- 搜索区域 -->
|
||
<a-form
|
||
ref="formRef"
|
||
:model="formState"
|
||
layout="inline"
|
||
class="search-form"
|
||
>
|
||
<a-form-item label="基地名称" name="dataDimensionVal">
|
||
<a-select
|
||
v-model:value="formState.dataDimensionVal"
|
||
placeholder="请选择"
|
||
style="width: 200px"
|
||
@change="handleJdChange"
|
||
>
|
||
<a-select-option
|
||
v-for="item in jdList"
|
||
:key="item.wbsCode"
|
||
:value="item.wbsCode"
|
||
>
|
||
{{ item.wbsName }}
|
||
</a-select-option>
|
||
</a-select>
|
||
</a-form-item>
|
||
|
||
<a-form-item label="断面名称" name="stcd">
|
||
<a-select
|
||
v-model:value="formState.stcd"
|
||
placeholder="请选择"
|
||
style="width: 200px"
|
||
:loading="selectLoading"
|
||
>
|
||
<a-select-option
|
||
v-for="item in dmList"
|
||
:key="item.value"
|
||
:value="item.value"
|
||
>
|
||
{{ item.label }}
|
||
</a-select-option>
|
||
</a-select>
|
||
</a-form-item>
|
||
|
||
<a-form-item label="月份" name="tm">
|
||
<a-date-picker
|
||
v-model:value="formState.tm"
|
||
picker="month"
|
||
placeholder="请选择月份"
|
||
style="width: 200px"
|
||
format="YYYY-MM"
|
||
value-format="YYYY-MM-DD HH:mm:ss"
|
||
/>
|
||
</a-form-item>
|
||
|
||
<a-form-item>
|
||
<a-space>
|
||
<a-button type="primary" @click="handleSearch">查询</a-button>
|
||
<a-button :loading="exportLoading" @click="handleExport">
|
||
导出
|
||
</a-button>
|
||
</a-space>
|
||
</a-form-item>
|
||
</a-form>
|
||
<BasicTable
|
||
ref="tableRef"
|
||
:scrollY="460"
|
||
:columns="columns"
|
||
:list-url="yearDetailGetKendoListCust"
|
||
:search-params="{ sort: sort }"
|
||
:transform-data="customTransform"
|
||
>
|
||
<template #action="{ record }">
|
||
<a @click="handleViewDetail(record)" class="text_hocer">查看详情</a>
|
||
</template>
|
||
</BasicTable>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, reactive, computed, onMounted, watch } from 'vue';
|
||
import dayjs, { Dayjs } from 'dayjs';
|
||
import { message } from 'ant-design-vue';
|
||
import { getVmsstbprpt, yearDetailGetKendoListCust } from '@/api/sw';
|
||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||
import BasicTable from '@/components/BasicTable/index.vue';
|
||
import { useModelStore } from '@/store/modules/model';
|
||
|
||
const modelStore = useModelStore();
|
||
// 类型定义
|
||
interface FormState {
|
||
dataDimensionVal: string | number | null;
|
||
tm: string | Dayjs | null;
|
||
stcd: string;
|
||
}
|
||
|
||
interface TableFilter {
|
||
startDt: string;
|
||
endDt: string;
|
||
stcd: string;
|
||
}
|
||
|
||
// Props
|
||
const props = defineProps<{
|
||
tm?: string;
|
||
dataDimensionVal?: string | number;
|
||
stcd?: string;
|
||
}>();
|
||
|
||
// Store
|
||
const jidiStore = useJidiSelectEventStore();
|
||
|
||
// Refs
|
||
const tableRef = ref();
|
||
const timeRef = ref(props.tm || '');
|
||
|
||
// State
|
||
const formState = reactive<FormState>({
|
||
dataDimensionVal: props.dataDimensionVal || '',
|
||
tm: props.tm ? dayjs(props.tm) : null,
|
||
stcd: props.stcd || ''
|
||
});
|
||
const sort = [
|
||
{
|
||
field: 'tm',
|
||
dir: 'desc'
|
||
}
|
||
];
|
||
const selectLoading = ref(false);
|
||
const exportLoading = ref(false);
|
||
const mapModalVisible = ref(false);
|
||
const modalData = ref<any>({});
|
||
const dmList = ref<Array<{ label: string; value: string }>>([]);
|
||
const isFirstLoad = ref(true);
|
||
|
||
// 基地列表(从 store 获取)
|
||
const jdList = computed(() => {
|
||
return jidiStore.jidiData || [];
|
||
});
|
||
// 表格列定义
|
||
const columns = [
|
||
{
|
||
title: '日期',
|
||
dataIndex: 'dt',
|
||
key: 'dt',
|
||
width: 120,
|
||
customRender: ({ text }: any) =>
|
||
text ? dayjs(text).format('YYYY-MM-DD') : '-'
|
||
},
|
||
{
|
||
title: '日均水温(℃)实测值',
|
||
dataIndex: 'wt',
|
||
key: 'wt',
|
||
width: 160
|
||
},
|
||
{
|
||
title: '日均水温(℃)去年同期',
|
||
dataIndex: 'beforeWt',
|
||
key: 'beforeWt',
|
||
width: 180
|
||
},
|
||
{
|
||
title: '天然值',
|
||
dataIndex: 'naturalTemp',
|
||
key: 'naturalTemp',
|
||
width: 120,
|
||
customRender: ({ text }: any) => (text ? Number(text).toFixed(1) : '-')
|
||
},
|
||
{
|
||
title: '操作',
|
||
key: 'action',
|
||
width: 100,
|
||
align: 'center' as const,
|
||
fixed: 'right' as const,
|
||
slots: { customRender: 'action' }
|
||
}
|
||
];
|
||
|
||
// API 调用函数
|
||
const getTableDataApi = async (params: any) => {
|
||
try {
|
||
// const res = await yearListGetKendoListCust(requestParams)
|
||
} catch (error) {}
|
||
};
|
||
|
||
// 获取断面列表
|
||
const fetchDmData = async () => {
|
||
if (!formState.dataDimensionVal) return;
|
||
|
||
try {
|
||
selectLoading.value = true;
|
||
const res = await getVmsstbprpt({
|
||
filter: {
|
||
logic: 'and',
|
||
filters: [
|
||
{
|
||
field: 'sttpFullPath',
|
||
operator: 'contains',
|
||
value: 'ENV,ENVM,WT,'
|
||
},
|
||
{
|
||
field: 'sttpCode',
|
||
operator: 'eq',
|
||
value: 'WTRV'
|
||
},
|
||
formState.dataDimensionVal != 'all'
|
||
? {
|
||
field: 'baseId',
|
||
operator: 'contains',
|
||
value: formState.dataDimensionVal
|
||
}
|
||
: null
|
||
].filter(Boolean)
|
||
},
|
||
select: [
|
||
'stcd',
|
||
'stnm',
|
||
'lgtd',
|
||
'lttd',
|
||
'baseId',
|
||
'baseName',
|
||
'siteStepSort'
|
||
]
|
||
// sort: [{ field: 'rstcdStepSort', dir: 'desc' }]
|
||
});
|
||
|
||
const resData = res?.data?.data || res?.data || [];
|
||
|
||
if (resData.length > 0) {
|
||
dmList.value = resData.map((item: any) => ({
|
||
label: item.stnm,
|
||
value: item.stcd
|
||
}));
|
||
|
||
// 如果是首次加载且有传入的 stcd,设置默认值
|
||
if (props.stcd) {
|
||
formState.stcd = props.stcd;
|
||
isFirstLoad.value = false;
|
||
} else {
|
||
// 非首次加载时,自动选择第一个
|
||
formState.stcd = dmList.value[0].value;
|
||
}
|
||
} else {
|
||
dmList.value = [];
|
||
formState.stcd = '';
|
||
}
|
||
} catch (error) {
|
||
console.error('获取断面列表失败:', error);
|
||
message.error('获取断面列表失败');
|
||
} finally {
|
||
selectLoading.value = false;
|
||
}
|
||
};
|
||
|
||
// 基地变化处理
|
||
const handleJdChange = (value: string) => {
|
||
formState.stcd = '';
|
||
dmList.value = [];
|
||
fetchDmData();
|
||
};
|
||
|
||
// 搜索处理
|
||
const handleSearch = async () => {
|
||
const tmValue = dayjs.isDayjs(formState.tm)
|
||
? formState.tm
|
||
: dayjs(formState.tm);
|
||
const filter = {
|
||
logic: 'and',
|
||
filters: [
|
||
{
|
||
field: 'stcd',
|
||
operator: 'eq',
|
||
dataType: 'string',
|
||
value: formState.stcd
|
||
},
|
||
{
|
||
field: 'dt',
|
||
operator: 'gte',
|
||
dataType: 'date',
|
||
value: tmValue.startOf('month').format('YYYY-MM-DD HH:mm:ss')
|
||
},
|
||
{
|
||
field: 'dt',
|
||
operator: 'lte',
|
||
dataType: 'date',
|
||
value: tmValue.endOf('month').format('YYYY-MM-DD HH:mm:ss')
|
||
}
|
||
]
|
||
};
|
||
|
||
// 刷新表格
|
||
tableRef.value?.getList(filter);
|
||
};
|
||
|
||
// 导出处理
|
||
const handleExport = async () => {};
|
||
|
||
// 查看详情
|
||
const handleViewDetail = (record: any) => {
|
||
modelStore.modalVisible = true;
|
||
modelStore.params.sttp = 'WT';
|
||
modelStore.title = record.stnm + '详情信息';
|
||
modelStore.params.stcd = record.stcd;
|
||
};
|
||
|
||
// 关闭弹窗
|
||
const handleModalClose = () => {
|
||
mapModalVisible.value = false;
|
||
modalData.value = {};
|
||
};
|
||
const customTransform = (res: any) => {
|
||
console.log('表格数据:', res);
|
||
return {
|
||
records: res?.data?.data || [],
|
||
total: res?.data?.total || 0
|
||
};
|
||
};
|
||
|
||
// 监听props变化
|
||
watch(
|
||
() => [props.tm, props.dataDimensionVal, props.stcd],
|
||
async (
|
||
[newTm, newDataDimensionVal, newStcd],
|
||
[oldTm, oldDataDimensionVal, oldStcd]
|
||
) => {
|
||
// 只有当值真正发生变化时才处理
|
||
if (
|
||
newTm !== oldTm ||
|
||
newDataDimensionVal !== oldDataDimensionVal ||
|
||
newStcd !== oldStcd
|
||
) {
|
||
// 更新formState
|
||
formState.tm = newTm ? dayjs(newTm) : null;
|
||
formState.dataDimensionVal = newDataDimensionVal || '';
|
||
formState.stcd = String(newStcd || '');
|
||
|
||
// 如果基地发生变化,需要重新获取断面列表
|
||
if (newDataDimensionVal !== oldDataDimensionVal && newDataDimensionVal) {
|
||
await fetchDmData();
|
||
// 请求数据
|
||
handleSearch();
|
||
}
|
||
}
|
||
},
|
||
{ deep: true }
|
||
);
|
||
|
||
// 监听基地变化
|
||
watch(
|
||
() => formState.dataDimensionVal,
|
||
async newVal => {
|
||
if (newVal) {
|
||
await fetchDmData();
|
||
handleSearch();
|
||
}
|
||
}
|
||
);
|
||
|
||
// 初始化
|
||
onMounted(async () => {
|
||
if (formState.dataDimensionVal) {
|
||
await fetchDmData();
|
||
handleSearch();
|
||
}
|
||
});
|
||
|
||
// 暴露方法给父组件
|
||
defineExpose({
|
||
handleSearch
|
||
});
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.year-average-container {
|
||
height: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 600px;
|
||
|
||
.search-form {
|
||
// padding: 16px;
|
||
background: #fff;
|
||
// margin-bottom: 16px;
|
||
border-radius: 4px;
|
||
|
||
:deep(.ant-form-item) {
|
||
margin-bottom: 16px;
|
||
}
|
||
}
|
||
|
||
.table-container {
|
||
flex: 1;
|
||
overflow: hidden;
|
||
background: #fff;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.text-hocer {
|
||
color: #2f6b98;
|
||
|
||
&:hover {
|
||
color: #40a9ff;
|
||
}
|
||
}
|
||
}
|
||
|
||
.text_hocer {
|
||
color: #2f6b98;
|
||
}
|
||
|
||
.text_hocer:hover {
|
||
color: #40a9ff;
|
||
}
|
||
</style>
|