You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
386 lines
18 KiB
386 lines
18 KiB
<template> |
|
<div class="app-container app-container-bg"> |
|
<el-card class="first-card" ref='firstCard' shadow="always"> |
|
<el-form :model="queryParams" ref="queryForm" :inline="true" @submit.native.prevent> |
|
<el-form-item label="选择站点"> |
|
<el-tree-select filterable :props="{ value: 'stnmId', label: 'name' }" v-model="queryParams.stnmId" style="width: 240px" :data="treeSelectOptions" node-key="id" /> |
|
</el-form-item> |
|
<el-form-item label="开始时间"> |
|
<el-date-picker :clearable="false" v-model="queryParams.startTime" type="datetime" value-format="MM-DD HH:mm" format="YYYY-MM-DD HH:mm:ss" placeholder="选择开始时间" :disabled-date="disabledStartDate"> |
|
</el-date-picker> |
|
</el-form-item> |
|
<el-form-item label="结束时间"> |
|
<el-date-picker :clearable="false" v-model="queryParams.endTime" type="datetime" value-format="MM-DD HH:mm" format="YYYY-MM-DD HH:mm:ss" placeholder="选择结束时间" :disabled-date="disabledEndDate"> |
|
</el-date-picker> |
|
</el-form-item> |
|
<br /> |
|
<el-form-item label="年份区间"> |
|
<el-date-picker :clearable="false" class="picker-year" style="width:180px" v-model="yearstart" type="year" value-format="YYYY" placeholder="选择开始年" @change="changeYearStart"> |
|
</el-date-picker> |
|
<span class="pr10 pl10"> -</span> |
|
<el-date-picker :clearable="false" class="picker-year" style="width:180px" v-model="yearend" type="year" value-format="YYYY" placeholder="选择结束年" @change="changeYearEnd"> |
|
</el-date-picker> |
|
</el-form-item> |
|
<el-form-item> |
|
<el-button type="primary" icon="Search" @click="handleQuery">查询</el-button> |
|
<!-- <el-button type="warning" icon="Download" @click="handleExport">下载</el-button> --> |
|
</el-form-item> |
|
</el-form> |
|
</el-card> |
|
|
|
<div class="el-card-p card-shadow carder-border mt10 pad10" style="max-width: 100%; overflow-x: hidden;padding-top:0" v-loading="loading"> |
|
<div class="main-table-header sticky-header"> |
|
<div class="table-title"> |
|
<span class="pr10" v-if="stnm!==''">{{stnm}}</span> |
|
<span v-else>{{tableTitle}}</span> |
|
</div> |
|
<div class="table-time mb5"> |
|
<div> |
|
<span>年份: </span><span id="title1">{{queryParams.years }}</span> |
|
</div> |
|
<div> |
|
<span>单位: </span><span id="title2">{{stationType=='E'?'m³/s':'m'}}</span> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<el-table v-table-height border :data="tableData" :span-method="arraySpanMethod" style="width: 100%;"> |
|
<el-table-column prop="year" label="年份" :align="alignment"> |
|
</el-table-column> |
|
<el-table-column v-if="stationType == 'D'" prop="nvalue" label="当前潮位" :align="alignment"> |
|
</el-table-column> |
|
<el-table-column v-if="stationType != 'D' && stationType != 'E'" prop="nvalue" label="当前水位" :align="alignment"> |
|
</el-table-column> |
|
<el-table-column v-if="stationType=='C'" prop="swValue" label="当前库容" :align="alignment"> |
|
</el-table-column> |
|
<el-table-column v-if="stationType == 'E'" prop="nvalue" label="当前流量" :align="alignment"> |
|
</el-table-column> |
|
<el-table-column v-if="stationType == 'D'" prop="value" label="平均潮位" :align="alignment"> |
|
</el-table-column> |
|
<el-table-column v-if="stationType != 'D' && stationType != 'E'" prop="value" label="平均水位" :align="alignment"> |
|
</el-table-column> |
|
<el-table-column v-if="stationType == 'E'" prop="value" label="平均流量" :align="alignment"> |
|
</el-table-column> |
|
<el-table-column label="最高潮位" :align="alignment" v-if="stationType == 'D'"> |
|
<el-table-column prop="maxvalue" label="潮位" :align="alignment"> |
|
</el-table-column> |
|
<el-table-column label="时间" :align="alignment" width="180"> |
|
<template #default="scope"> |
|
<span>{{ parseTime(scope.row.maxtm) }}</span> |
|
</template> |
|
</el-table-column> |
|
</el-table-column> |
|
<el-table-column label="最高水位" :align="alignment" v-if="stationType != 'D' && stationType != 'E'"> |
|
<el-table-column prop="maxvalue" label="水位" :align="alignment"> |
|
</el-table-column> |
|
<el-table-column label="时间" :align="alignment" width="180"> |
|
<template #default="scope"> |
|
<span>{{ parseTime(scope.row.maxtm) }}</span> |
|
</template> |
|
</el-table-column> |
|
</el-table-column> |
|
<el-table-column label="最高流量" :align="alignment" v-if="stationType == 'E'"> |
|
<el-table-column prop="maxvalue" label="流量" :align="alignment"> |
|
</el-table-column> |
|
<el-table-column label="时间" :align="alignment" width="180"> |
|
<template #default="scope"> |
|
<span>{{ parseTime(scope.row.maxtm) }}</span> |
|
</template> |
|
</el-table-column> |
|
</el-table-column> |
|
<el-table-column label="最低潮位" :align="alignment" v-if="stationType == 'D'"> |
|
<el-table-column prop="minvalue" label="潮位" :align="alignment"> |
|
</el-table-column> |
|
<el-table-column label="时间" :align="alignment" width="180"> |
|
<template #default="scope"> |
|
<span>{{ parseTime(scope.row.mintm) }}</span> |
|
</template> |
|
</el-table-column> |
|
</el-table-column> |
|
<el-table-column label="最低水位" :align="alignment" v-if="stationType != 'D' && stationType != 'E'"> |
|
<el-table-column prop="minvalue" label="水位" :align="alignment"> |
|
</el-table-column> |
|
<el-table-column label="时间" :align="alignment" width="180"> |
|
<template #default="scope"> |
|
<span>{{ parseTime(scope.row.mintm) }}</span> |
|
</template> |
|
</el-table-column> |
|
</el-table-column> |
|
<el-table-column label="最低流量" :align="alignment" v-if="stationType == 'E'"> |
|
<el-table-column prop="minvalue" label="流量" :align="alignment"> |
|
</el-table-column> |
|
<el-table-column label="时间" :align="alignment" width="180"> |
|
<template #default="scope"> |
|
<span>{{ parseTime(scope.row.mintm) }}</span> |
|
</template> |
|
</el-table-column> |
|
</el-table-column> |
|
</el-table> |
|
</div> |
|
|
|
</div> |
|
</template> |
|
<script setup> |
|
import dayjs from 'dayjs'; |
|
import singleStation from '@/components/SingleStation/index.vue' |
|
import { ref, reactive, onMounted } from 'vue'; |
|
|
|
const props = defineProps({ |
|
tableTitle: { |
|
type: String, |
|
default: '表格标题' |
|
}, |
|
stationType: { |
|
type: String, |
|
default: 'A' |
|
}, |
|
requestPrefix: { |
|
type: String, |
|
default: "" |
|
} |
|
}) |
|
|
|
const { proxy } = getCurrentInstance() |
|
const alignment = 'center' |
|
const type = computed(() => { |
|
switch (props.stationType) { |
|
case 'A': |
|
return 'rain'; |
|
case 'B': |
|
return 'river'; |
|
case 'C': |
|
return 'rsvr'; |
|
case 'D': |
|
return 'tide'; |
|
case 'E': |
|
return 'q_qflow'; |
|
} |
|
}); |
|
const tablename = computed(() => { |
|
switch (props.stationType) { |
|
case 'D': |
|
return '潮位过程表'; |
|
case 'E': |
|
return '流量过程表'; |
|
default: |
|
return '水位过程表'; |
|
} |
|
}); |
|
const loading = ref(false); |
|
const tableData = ref([]); |
|
const yearstart = ref(dayjs().subtract(1, 'year').format('YYYY')) |
|
const yearend = ref(dayjs().format('YYYY')) |
|
const queryParams = reactive({ |
|
startTime: dayjs().subtract(30, 'day').format('MM-DD 08:00'), |
|
endTime: dayjs().format('MM-DD 08:00'), |
|
years: `${yearstart.value}-${yearend.value}`, |
|
stnmIds: '', |
|
type: type.value |
|
}); |
|
|
|
let total = ref(0) |
|
let dataCount = ref(0) |
|
const stnm = ref('') |
|
const getList = async () => { |
|
loading.value = true; |
|
let url = `/report/${props.requestPrefix}` |
|
try { |
|
const res = await proxy.axiosGet(url, queryParams) |
|
if (res.code == 0) { |
|
let data = res.data.list |
|
let { avg, max, min, list } = res.data |
|
tableData.value = data; |
|
|
|
// 计算 swValue 的统计数据 |
|
let swValues = list.filter(item => item.swValue !== undefined && item.swValue !== '').map(item => parseFloat(item.swValue)); |
|
let avgSwValue = swValues.length > 0 ? swValues.reduce((a, b) => a + b, 0) / swValues.length : ""; |
|
let maxSwItem = list.reduce((max, item) => { |
|
if (item.swValue === undefined || item.swValue === '') return max; |
|
let value = parseFloat(item.swValue); |
|
return !max || value > parseFloat(max.swValue) ? item : max; |
|
}, null); |
|
let minSwItem = list.reduce((min, item) => { |
|
if (item.swValue === undefined || item.swValue === '') return min; |
|
let value = parseFloat(item.swValue); |
|
return !min || value < parseFloat(min.swValue) ? item : min; |
|
}, null); |
|
tableData.value.push({ |
|
year: "平均", |
|
swValue: parseInt(avgSwValue), |
|
nvalue: (avg[0] == 0 ? "" : avg[0]), |
|
value: (avg[1] == 0 ? "" : avg[1]), |
|
maxvalue: (avg[2] == 0 ? "" : avg[2]), |
|
minvalue: (avg[3] == 0 ? "" : avg[3]), |
|
}); |
|
tableData.value.push({ |
|
year: "最高", |
|
swValue: maxSwItem ? maxSwItem.swValue : "", |
|
nvalue: (typeof (max[0].nvalue) == "undefined" ? "" : max[0].nvalue), |
|
value: (typeof (max[1].value) == "undefined" ? "" : max[1].value), |
|
maxvalue: (typeof (max[3].maxvalue) == "undefined" ? "" : max[3].maxvalue), |
|
minvalue: (typeof (max[4].minvalue) == "undefined" ? "" : max[4].minvalue), |
|
}); |
|
tableData.value.push({ |
|
year: "时间", |
|
swValue: maxSwItem ? maxSwItem.year : "", |
|
nvalue: (typeof (max[0].year) == "undefined" ? "" : max[0].year), |
|
value: (typeof (max[1].year) == "undefined" ? "" : max[1].year), |
|
maxvalue: (proxy.parseTime(typeof (max[3].maxtm)) == "undefined" ? "" : proxy.parseTime(max[3].maxtm)), |
|
minvalue: (proxy.parseTime(typeof (max[4].mintm)) == "undefined" ? "" : proxy.parseTime(max[4].mintm)), |
|
}); |
|
tableData.value.push({ |
|
year: "最低", |
|
swValue: minSwItem ? minSwItem.swValue : "", |
|
nvalue: (typeof (min[0].nvalue) == "undefined" ? "" : min[0].nvalue), |
|
value: (typeof (min[1].value) == "undefined" ? "" : min[1].value), |
|
maxvalue: (typeof (min[2].maxvalue) == "undefined" ? "" : min[2].maxvalue), |
|
minvalue: (typeof (min[3].minvalue) == "undefined" ? "" : min[3].minvalue), |
|
}); |
|
tableData.value.push({ |
|
year: "时间", |
|
swValue: minSwItem ? minSwItem.year : "", |
|
nvalue: (typeof (min[0].year) == "undefined" ? "" : min[0].year), |
|
value: (typeof (min[1].year) == "undefined" ? "" : min[1].year), |
|
maxvalue: (proxy.parseTime(typeof (min[2].maxtm)) == "undefined" ? "" : proxy.parseTime(min[2].maxtm)), |
|
minvalue: (proxy.parseTime(typeof (min[3].mintm)) == "undefined" ? "" : proxy.parseTime(min[3].mintm)), |
|
}); |
|
dataCount.value = tableData.value.length; |
|
} |
|
} catch (error) { |
|
console.error(error) |
|
} finally { |
|
// 确保在请求完成后隐藏loading |
|
loading.value = false |
|
} |
|
} |
|
const changeYearStart = (val) => { |
|
yearstart.value = val |
|
queryParams.years = `${yearstart.value}-${yearend.value}` |
|
getList() |
|
} |
|
const changeYearEnd = (val) => { |
|
yearend.value = val |
|
queryParams.years = `${yearstart.value}-${yearend.value}` |
|
getList() |
|
} |
|
|
|
// 优化后的获取上一行月份的方法 |
|
const getPrevRow = (scope, field, type) => { |
|
const rowIndex = scope.$index; |
|
const data = scope.store.states.data; |
|
|
|
// 如果是第一行,返回null |
|
if (rowIndex === 0) return null; |
|
|
|
// 找到上一个非空行的月份 |
|
let prevRowIndex = rowIndex - 1; |
|
while (prevRowIndex >= 0 && (!data.value[prevRowIndex][field] || data.value[prevRowIndex][field] === '')) { |
|
prevRowIndex--; |
|
} |
|
if (type == '1') { |
|
field = 'month' |
|
} |
|
let result = prevRowIndex >= 0 ? data.value[prevRowIndex][field] : null; |
|
// 如果找到有效的上一行数据,返回其月份;否则返回null |
|
return result |
|
}; |
|
|
|
const treeSelectOptions = ref([]) |
|
const getTreeStation = async () => { |
|
loading.value = true; |
|
try { |
|
let res = await proxy.axiosGet('/basic/stype/getTreeStation2/' + proxy.stationType); |
|
if (res.code == 0) { |
|
treeSelectOptions.value = res.data |
|
// 设置默认值为第一个叶子节点的stnmId |
|
if (treeSelectOptions.value.length > 0) { |
|
const firstLeafNode = findFirstLeafNode(treeSelectOptions.value); |
|
if (firstLeafNode) { |
|
queryParams.stnmId = firstLeafNode.stnmId; |
|
stnm.value = `${firstLeafNode.name}${queryParams.startTime} ~ ${queryParams.endTime}${tablename.value}`; |
|
nextTick(() => { |
|
getList() |
|
}) |
|
} |
|
} |
|
} |
|
} catch (error) { |
|
|
|
} |
|
} |
|
// 查找树结构中的第一个叶子节点 |
|
const findFirstLeafNode = (nodes) => { |
|
for (let node of nodes) { |
|
// 如果节点有子节点,则递归查找 |
|
if (node.children && node.children.length > 0) { |
|
const leaf = findFirstLeafNode(node.children); |
|
if (leaf) { |
|
return leaf; |
|
} |
|
} |
|
// 如果节点没有子节点,则为叶子节点 |
|
else if (node.stnmId) { |
|
return node; |
|
} |
|
} |
|
return null; |
|
} |
|
// 搜索按钮操作 |
|
const handleQuery = () => { |
|
getList() |
|
|
|
} |
|
// 下载按钮操作 |
|
const handleExport = () => { } |
|
onMounted(() => { |
|
getTreeStation() |
|
}) |
|
const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => { |
|
if (dataCount.value > 4) { |
|
if (rowIndex > dataCount.value - 6) { |
|
if (props.stationType == 'C') { |
|
if (columnIndex === 4 || columnIndex === 6) { |
|
return [1, 2]; |
|
} else if (columnIndex === 5 || columnIndex === 7) { |
|
return [0, 0]; |
|
} |
|
} else { |
|
if (columnIndex === 3 || columnIndex === 5) { |
|
return [1, 2]; |
|
} else if (columnIndex === 4 || columnIndex === 6) { |
|
return [0, 0]; |
|
} |
|
} |
|
|
|
} |
|
} |
|
} |
|
|
|
// 禁用开始时间选择器中大于当前时间和结束时间的日期 |
|
const disabledStartDate = (time) => { |
|
const endTime = queryParams.endTime ? dayjs(queryParams.endTime) : null; |
|
return dayjs(time).isAfter(dayjs()) || |
|
(endTime && dayjs(time).isAfter(endTime)); |
|
}; |
|
|
|
// 禁用结束时间选择器中大于当前时间和小于开始时间的日期 |
|
const disabledEndDate = (time) => { |
|
const startTime = queryParams.startTime ? dayjs(queryParams.startTime) : null; |
|
return dayjs(time).isAfter(dayjs()) || |
|
(startTime && dayjs(time).isBefore(startTime)); |
|
}; |
|
</script> |
|
<style scoped lang="scss"> |
|
.no-border-table :deep(.el-table__body-wrapper .el-table__cell) { |
|
border-bottom: 0 !important; |
|
} |
|
|
|
.no-border-table :deep(.el-table__body-wrapper .el-table__cell) { |
|
padding: 2px 0 !important; |
|
} |
|
|
|
.no-border-table :deep(.el-table__body-wrapper .el-table__row:nth-child(6n) .el-table__cell) { |
|
padding: 10px 0 !important; |
|
background-color: #f9f9f9; |
|
} |
|
</style> |