380 lines
10 KiB
Vue
380 lines
10 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 #bodyCell="{ column, record }">
|
||
<template v-if="column.key === 'action'">
|
||
<a @click="handleViewDetail(record)" class="text_hocer">查看详情</a>
|
||
</template>
|
||
</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
|
||
}
|
||
]
|
||
|
||
|
||
|
||
// 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_point";
|
||
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>
|