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>
|