10 changed files with 1339 additions and 11 deletions
@ -0,0 +1,29 @@ |
|||||||
|
import JSEncrypt from 'jsencrypt/bin/jsencrypt.min' |
||||||
|
|
||||||
|
// 密钥对生成 http://web.chacuo.net/netrsakeypair
|
||||||
|
|
||||||
|
const publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbqqN6/gsbl92/fqlVptUBll5x6GVguc9kKjlAjNGGJkjfCP4bwHP2WM6n0ZIPat/EpzhZfZ9HPkVxRi4fgg6Y0naAR0ktTv5jXM8AewjqYyvlKuVD2grEoGfpBJSp2EDHMCS+nPgx8cAfWNrQtztaF7ycV/yY2ahgqEnNdtTIOQIDAQAB' |
||||||
|
|
||||||
|
const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' + |
||||||
|
'7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' + |
||||||
|
'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' + |
||||||
|
'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' + |
||||||
|
'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' + |
||||||
|
'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' + |
||||||
|
'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' + |
||||||
|
'UP8iWi1Qw0Y=' |
||||||
|
|
||||||
|
// 加密
|
||||||
|
export function encrypt(txt) { |
||||||
|
const encryptor = new JSEncrypt() |
||||||
|
encryptor.setPublicKey(publicKey) // 设置公钥
|
||||||
|
return encryptor.encrypt(txt) // 对数据进行加密
|
||||||
|
} |
||||||
|
|
||||||
|
// 解密
|
||||||
|
export function decrypt(txt) { |
||||||
|
const encryptor = new JSEncrypt() |
||||||
|
encryptor.setPrivateKey(privateKey) // 设置私钥
|
||||||
|
return encryptor.decrypt(txt) // 对数据进行解密
|
||||||
|
} |
||||||
|
|
||||||
@ -0,0 +1,92 @@ |
|||||||
|
<template> |
||||||
|
<div class="report-rain"> |
||||||
|
<div class="tjfx-menu"> |
||||||
|
<el-select v-model="menu" placeholder="请选择"> |
||||||
|
<el-option v-for="dict in tjfxMenus" :key="dict.value" :label="dict.label" :value="dict.value" /> |
||||||
|
</el-select> |
||||||
|
</div> |
||||||
|
<!-- 添加加载状态和错误提示 --> |
||||||
|
<div v-if="componentError" class="error-message"> |
||||||
|
组件加载失败,请刷新页面重试 |
||||||
|
</div> |
||||||
|
<component v-else :is="currentComponent" :tableTitle="tableTitle"></component> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script setup> |
||||||
|
import { ref, computed, defineAsyncComponent } from 'vue' |
||||||
|
|
||||||
|
|
||||||
|
// 定义菜单选项 |
||||||
|
const tjfxMenus = [ |
||||||
|
{ |
||||||
|
value: '1', |
||||||
|
label: '潮位观测月报表' |
||||||
|
}, |
||||||
|
{ |
||||||
|
value: '2', |
||||||
|
label: '逐潮高低潮位表' |
||||||
|
}, { |
||||||
|
value: '3', |
||||||
|
label: '逐日平均潮位表' |
||||||
|
}, { |
||||||
|
value: '4', |
||||||
|
label: '月年平均潮位对照表' |
||||||
|
}, { |
||||||
|
value: '5', |
||||||
|
label: '潮位月年统计表' |
||||||
|
} |
||||||
|
] |
||||||
|
|
||||||
|
// 当前选中的菜单 |
||||||
|
const menu = ref(tjfxMenus.length > 0 ? tjfxMenus[0].value : '') |
||||||
|
|
||||||
|
// 动态组件映射 |
||||||
|
const componentMap = { |
||||||
|
'1': defineAsyncComponent(() => import('@/views/report/tide3/index.vue')), |
||||||
|
'2': defineAsyncComponent(() => import('@/views/report/tide1/index.vue')), |
||||||
|
'3': defineAsyncComponent(() => import('@/views/report/zrtide/index.vue')), |
||||||
|
'4': defineAsyncComponent(() => import('@/views/report/gzyntidedzb/index.vue')), |
||||||
|
'5': defineAsyncComponent(() => import('@/views/report/tide2/index.vue')), |
||||||
|
} |
||||||
|
// 添加错误处理 |
||||||
|
const componentError = ref(false) |
||||||
|
|
||||||
|
onErrorCaptured((error) => { |
||||||
|
componentError.value = true |
||||||
|
return true |
||||||
|
}) |
||||||
|
|
||||||
|
// 计算当前应该显示的组件 |
||||||
|
const currentComponent = computed(() => { |
||||||
|
return componentMap[menu.value] |
||||||
|
}) |
||||||
|
// 原代码有误,tjfxMenus 中的对象没有 name 属性 |
||||||
|
const tableTitle = computed(() => { |
||||||
|
const currentItem = tjfxMenus.find(item => item.value === menu.value); |
||||||
|
return currentItem ? currentItem.label : ''; |
||||||
|
}) |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss"> |
||||||
|
.tjfx-menu { |
||||||
|
position: absolute; |
||||||
|
right: 25px; |
||||||
|
top: 30px; |
||||||
|
z-index: 999999; |
||||||
|
|
||||||
|
.el-input__wrapper { |
||||||
|
background: #10163A; |
||||||
|
} |
||||||
|
|
||||||
|
.el-input__inner { |
||||||
|
background: #10163A; |
||||||
|
color: #fff; |
||||||
|
border-color: #10163A; |
||||||
|
} |
||||||
|
|
||||||
|
.el-select .el-input .el-select__caret { |
||||||
|
color: #fff !important; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,408 @@ |
|||||||
|
<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="选择站点"> |
||||||
|
<singleStation ref="singleStationRef" :stationType="stationType" @stationChange="handleStationChange" /> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="年份"> |
||||||
|
<el-date-picker v-model="queryParams.year" type="year" value-format="YYYY" placeholder="选择年" :clearable="false"> |
||||||
|
</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 scroll-bar " style="max-width: 100%; overflow-x: hidden;"> |
||||||
|
<div class="main-table-header" style="width: 80%;margin:0 auto"> |
||||||
|
<div class="table-title">{{tableTitle}}</div> |
||||||
|
<div class="table-time mb5"> |
||||||
|
<div> |
||||||
|
<span>年份: </span><span id="title1">{{queryParams.year }}</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<span>测站编码: </span><span id="title2">{{queryParams.stnmId}}</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<span>单位:潮差,(m),历时,(时分)</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-table class="report-table merge-header" v-loading="loading" :data="tableData" style="width: 80%;margin:0 auto" :table-layout="tableLayout" :span-method="arraySpanMethod" :row-class-name="getRowClassName"> |
||||||
|
<el-table-column v-for="(item, index) in columnData" :key="index" :label="item.label" :align="alignment" :prop="item.prop"> |
||||||
|
<el-table-column v-if="item.children" v-for="(child, childIndex) in item.children" :key="childIndex" :label="child.label" :prop="child.prop" :width="child.width" :align="alignment"> |
||||||
|
</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: '表格标题' |
||||||
|
}, |
||||||
|
|
||||||
|
}) |
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance() |
||||||
|
const alignment = 'center' |
||||||
|
const stationType = 'D' |
||||||
|
const tableLayout = ref('fixed') |
||||||
|
const singleStationRef = ref(null) |
||||||
|
// 新增处理站点变化的函数 |
||||||
|
const handleStationChange = (stnmId) => { |
||||||
|
queryParams.stnmId = stnmId |
||||||
|
if (stnmId == undefined) { |
||||||
|
proxy.$modal.msgWarning("请选择站点后查询"); |
||||||
|
return |
||||||
|
} else { |
||||||
|
loading.value = true; |
||||||
|
getList() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const loading = ref(false); |
||||||
|
const tableData = ref([]); |
||||||
|
const queryParams = reactive({ |
||||||
|
year: dayjs(new Date()).format('YYYY'), |
||||||
|
}); |
||||||
|
const staid = ref('') |
||||||
|
const title = ref('') |
||||||
|
const getList = async () => { |
||||||
|
loading.value = true; |
||||||
|
try { |
||||||
|
const res = await proxy.axiosGet('/report/tideyntj', queryParams) |
||||||
|
if (res.code == 0) { |
||||||
|
if (res.data == null) { |
||||||
|
proxy.$modal.msgWarning("该站点没有数据"); |
||||||
|
tableData.value = [] |
||||||
|
return |
||||||
|
} |
||||||
|
let data = res.data |
||||||
|
let sourceData = data; // 兼容两种数据格式 |
||||||
|
let list = [] |
||||||
|
for (let i = 0; i < 42; i++) { |
||||||
|
let projectText = getProjectText(i); |
||||||
|
let typeText = getTypeText(i); |
||||||
|
let dateText = getDateText(i); |
||||||
|
// 计算应该使用哪一组数据(0-高潮潮位, 1-低潮潮位, 2-涨潮潮差, 3-落潮潮差, 4-涨潮历时, 5-落潮历时) |
||||||
|
const dataIndex = Math.floor(i / 7); |
||||||
|
// 计算在当前组内的索引(0-6) |
||||||
|
const innerIndex = i % 7; |
||||||
|
|
||||||
|
// 获取每个月份的值 |
||||||
|
const monthValues = {}; |
||||||
|
for (let month = 1; month <= data.length - 1; month++) { |
||||||
|
monthValues[getMonthKey(month)] = getValueByRule(sourceData, month, dataIndex, innerIndex); |
||||||
|
} |
||||||
|
|
||||||
|
// 获取全年值 |
||||||
|
const allValue = getAllValueByRule(sourceData, dataIndex, innerIndex); |
||||||
|
list.push({ |
||||||
|
Project: projectText, |
||||||
|
Type: typeText, |
||||||
|
Date: dateText, |
||||||
|
...monthValues, |
||||||
|
All: allValue |
||||||
|
}) |
||||||
|
|
||||||
|
} |
||||||
|
// 添加附注行 |
||||||
|
list.push({ |
||||||
|
Project: '附录', |
||||||
|
Jan: res.data.fuzhu |
||||||
|
}) |
||||||
|
tableData.value = list |
||||||
|
} |
||||||
|
} catch (error) { |
||||||
|
|
||||||
|
} finally { |
||||||
|
loading.value = false; |
||||||
|
} |
||||||
|
} |
||||||
|
// 获取月份键名 |
||||||
|
const getMonthKey = (month) => { |
||||||
|
const months = ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', |
||||||
|
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; |
||||||
|
return months[month]; |
||||||
|
} |
||||||
|
|
||||||
|
// 根据规则获取值 |
||||||
|
const getValueByRule = (sourceData, month, dataIndex, innerIndex) => { |
||||||
|
console.log(sourceData, month, dataIndex, innerIndex, 'sourceData, month, dataIndex, innerIndex') |
||||||
|
// 确保月份数据存在 |
||||||
|
if (!sourceData[month - 1] || !sourceData[month - 1][dataIndex]) { |
||||||
|
return ''; |
||||||
|
} |
||||||
|
|
||||||
|
const item = sourceData[month - 1][dataIndex]; |
||||||
|
return getValueFromItemByIndex(item, innerIndex); |
||||||
|
} |
||||||
|
|
||||||
|
// 根据索引从项目中获取值 |
||||||
|
const getValueFromItemByIndex = (item, innerIndex) => { |
||||||
|
switch (innerIndex) { |
||||||
|
case 0: return item.max || ''; |
||||||
|
case 1: return item.maxDate || ''; |
||||||
|
case 2: return item.maxNDate || ''; |
||||||
|
case 3: return item.min || ''; |
||||||
|
case 4: return item.minDate || ''; |
||||||
|
case 5: return item.minNDate || ''; |
||||||
|
case 6: return item.avg || ''; |
||||||
|
default: return ''; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 获取全年值 |
||||||
|
const getAllValueByRule = (sourceData, dataIndex, innerIndex) => { |
||||||
|
// 全年数据在最后一个月(13月)或者需要另外计算 |
||||||
|
let idx = sourceData.length - 1; |
||||||
|
const item = sourceData[idx][dataIndex]; |
||||||
|
if (item) { |
||||||
|
return getValueFromItemByIndex(item, innerIndex); |
||||||
|
} |
||||||
|
return ''; |
||||||
|
} |
||||||
|
const getProjectText = (i) => { |
||||||
|
let projectText = ''; |
||||||
|
const groupIndex = Math.floor(i / 7); |
||||||
|
switch (groupIndex) { |
||||||
|
case 0: |
||||||
|
projectText = '高潮潮位(m)'; |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
projectText = '低潮潮位(m)'; |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
projectText = '涨潮潮差(m)'; |
||||||
|
break; |
||||||
|
case 3: |
||||||
|
projectText = '落潮潮差(m)'; |
||||||
|
break; |
||||||
|
case 4: |
||||||
|
projectText = '涨潮历时'; |
||||||
|
break; |
||||||
|
case 5: |
||||||
|
projectText = '落潮历时'; |
||||||
|
break; |
||||||
|
} |
||||||
|
return projectText; |
||||||
|
} |
||||||
|
const getTypeText = (i) => { |
||||||
|
let typeText = ''; |
||||||
|
const innerIndex = i % 7; |
||||||
|
|
||||||
|
// 修改这里的逻辑,确保平均值行正确设置 |
||||||
|
if (innerIndex === 6) { // 每组第7行(索引6)应该是平均值 |
||||||
|
// 根据项目类型设置具体的平均值文本 |
||||||
|
const groupIndex = Math.floor(i / 7); |
||||||
|
switch (groupIndex) { |
||||||
|
case 0: |
||||||
|
case 1: |
||||||
|
typeText = '平均潮位'; |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
case 3: |
||||||
|
typeText = '平均潮差'; |
||||||
|
break; |
||||||
|
case 4: |
||||||
|
case 5: |
||||||
|
typeText = '平均历时'; |
||||||
|
break; |
||||||
|
} |
||||||
|
} else if ([0, 1, 2, 7, 8, 9, 14, 15, 16, 21, 22, 23, 28, 29, 30, 35, 36, 37].includes(i)) { |
||||||
|
typeText = '最高'; |
||||||
|
} else if ([3, 4, 5, 10, 11, 12, 17, 18, 19, 24, 25, 26, 31, 32, 33, 38, 39, 40].includes(i)) { |
||||||
|
typeText = '最低'; |
||||||
|
} |
||||||
|
return typeText |
||||||
|
} |
||||||
|
const getDateText = (i) => { |
||||||
|
let dateText = ''; |
||||||
|
switch (i % 7) { |
||||||
|
case 0: |
||||||
|
dateText = '潮位'; |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
dateText = '公历:日-时.分'; |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
dateText = '农历:月-日'; |
||||||
|
break; |
||||||
|
case 3: |
||||||
|
dateText = '潮位'; |
||||||
|
break; |
||||||
|
case 4: |
||||||
|
dateText = '公历:日-时.分'; |
||||||
|
break; |
||||||
|
case 5: |
||||||
|
dateText = '农历:月-日'; |
||||||
|
break; |
||||||
|
} |
||||||
|
return dateText |
||||||
|
} |
||||||
|
// 搜索按钮操作 |
||||||
|
const handleQuery = () => { |
||||||
|
getList() |
||||||
|
} |
||||||
|
// 下载按钮操作 |
||||||
|
const handleExport = () => { } |
||||||
|
onMounted(() => { }) |
||||||
|
const columnData = ref([ |
||||||
|
{ |
||||||
|
label: '项目', |
||||||
|
prop: 'Project', |
||||||
|
children: [ |
||||||
|
{ label: '项目', prop: 'Project', width: 60 }, |
||||||
|
{ label: '', prop: 'Type', width: 60 }, |
||||||
|
{ label: '', prop: 'Date', width: 120 } |
||||||
|
] |
||||||
|
}, |
||||||
|
{ label: '一月', prop: 'Jan' }, |
||||||
|
{ label: '二月', prop: 'Feb' }, |
||||||
|
{ label: '三月', prop: 'Mar' }, |
||||||
|
{ label: '四月', prop: 'Apr' }, |
||||||
|
{ label: '五月', prop: 'May' }, |
||||||
|
{ label: '六月', prop: 'Jun' }, |
||||||
|
{ label: '七月', prop: 'Jul' }, |
||||||
|
{ label: '八月', prop: 'Aug' }, |
||||||
|
{ label: '九月', prop: 'Sep' }, |
||||||
|
{ label: '十月', prop: 'Oct' }, |
||||||
|
{ label: '十一月', prop: 'Nov' }, |
||||||
|
{ label: '十二月', prop: 'Dec' }, |
||||||
|
{ label: '全年', prop: 'All' } |
||||||
|
]) |
||||||
|
|
||||||
|
const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => { |
||||||
|
// 处理附录行(最后一行) |
||||||
|
if (rowIndex === tableData.value.length - 1) { |
||||||
|
// 附录行的"附录"单元格(第一列)合并前三列 |
||||||
|
if (columnIndex === 0) { |
||||||
|
return { |
||||||
|
rowspan: 1, |
||||||
|
colspan: 3 |
||||||
|
}; |
||||||
|
} |
||||||
|
// 附录行的第二列和第三列需要隐藏 |
||||||
|
else if (columnIndex === 1 || columnIndex === 2) { |
||||||
|
return { |
||||||
|
rowspan: 0, |
||||||
|
colspan: 0 |
||||||
|
}; |
||||||
|
} |
||||||
|
// 附录行从第四列开始(即从"一月"列开始)合并为一列 |
||||||
|
else if (columnIndex === 3) { |
||||||
|
// 合并剩余的所有列(12个月+全年 = 13列) |
||||||
|
return { |
||||||
|
rowspan: 1, |
||||||
|
colspan: 13 |
||||||
|
}; |
||||||
|
} |
||||||
|
// 附录行的其他数据列隐藏 |
||||||
|
else { |
||||||
|
return { |
||||||
|
rowspan: 0, |
||||||
|
colspan: 0 |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 第0列(项目列)每7行合并一次 |
||||||
|
if (columnIndex === 0) { |
||||||
|
// 每组的第一行显示合并后的单元格 |
||||||
|
if (rowIndex % 7 === 0) { |
||||||
|
return { |
||||||
|
rowspan: 7, |
||||||
|
colspan: 1 |
||||||
|
}; |
||||||
|
} else { |
||||||
|
// 其他行隐藏 |
||||||
|
return { |
||||||
|
rowspan: 0, |
||||||
|
colspan: 0 |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
|
// 第1列(Type列)按数据内容合并 |
||||||
|
else if (columnIndex === 1) { |
||||||
|
const innerIndex = rowIndex % 7; // 组内索引(0-6) |
||||||
|
const isAverage = ['平均潮位', '平均潮差', '平均历时'].includes(tableData.value[rowIndex].Type); |
||||||
|
|
||||||
|
// 每组第0行,且为"最高"值时,合并前三行 |
||||||
|
if (innerIndex === 0 && tableData.value[rowIndex].Type === '最高') { |
||||||
|
return { |
||||||
|
rowspan: 3, |
||||||
|
colspan: 1 |
||||||
|
}; |
||||||
|
} |
||||||
|
// 每组第3行,且为"最低"值时,合并前三行 |
||||||
|
else if (innerIndex === 3 && tableData.value[rowIndex].Type === '最低') { |
||||||
|
return { |
||||||
|
rowspan: 3, |
||||||
|
colspan: 1 |
||||||
|
}; |
||||||
|
} |
||||||
|
// 每组第6行,且为平均值时,合并两列 |
||||||
|
else if (innerIndex === 6 && isAverage) { |
||||||
|
return { |
||||||
|
rowspan: 1, |
||||||
|
colspan: 2 |
||||||
|
}; |
||||||
|
} |
||||||
|
// 其他需要隐藏的行(包括每组的第1,2,4,5行,以及第6行但不是平均值的情况) |
||||||
|
else if ([1, 2, 4, 5].includes(innerIndex) || |
||||||
|
(innerIndex === 6 && !isAverage) || |
||||||
|
(innerIndex === 0 && tableData.value[rowIndex].Type !== '最高') || |
||||||
|
(innerIndex === 3 && tableData.value[rowIndex].Type !== '最低')) { |
||||||
|
return { |
||||||
|
rowspan: 0, |
||||||
|
colspan: 0 |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
|
// 第2列(Date列)需要处理平均值行的情况 |
||||||
|
else if (columnIndex === 2) { |
||||||
|
const innerIndex = rowIndex % 7; |
||||||
|
const isAverage = ['平均潮位', '平均潮差', '平均历时'].includes(tableData.value[rowIndex].Type); |
||||||
|
|
||||||
|
// 如果第1列是平均值且合并了两列,那么第2列的这一行需要隐藏 |
||||||
|
if (innerIndex === 6 && isAverage) { |
||||||
|
return { |
||||||
|
rowspan: 0, |
||||||
|
colspan: 0 |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
const getRowClassName = ({ row, rowIndex }) => { |
||||||
|
const n = rowIndex + 1; // 转换为从1开始的索引 |
||||||
|
// 可以用以下方式判断: |
||||||
|
if (n === 2 || n === 5) return 'small-font-row'; |
||||||
|
if (n === 9 || n === 12) return 'small-font-row'; |
||||||
|
if (n === 16 || n === 19) return 'small-font-row'; |
||||||
|
if (n === 23 || n === 26) return 'small-font-row'; |
||||||
|
if (n === 30 || n === 33) return 'small-font-row'; |
||||||
|
if (n === 37 || n === 40) return 'small-font-row'; |
||||||
|
return ''; |
||||||
|
}; |
||||||
|
</script> |
||||||
|
<style scoped lang='scss'> |
||||||
|
/* 隐藏子列的表头行 */ |
||||||
|
.merge-header :deep(.el-table__header tr:nth-child(2)) { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
/* 为特定行添加小字体样式 */ |
||||||
|
:deep(.small-font-row td) { |
||||||
|
font-size: 12px !important; |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,436 @@ |
|||||||
|
<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="选择站点"> |
||||||
|
<singleStation ref="singleStationRef" :stationType="stationType" @stationChange="handleStationChange" /> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="年份"> |
||||||
|
<el-date-picker v-model="queryParams.year" type="year" value-format="YYYY" placeholder="选择年" :clearable="false"> |
||||||
|
</el-date-picker> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="时段"> |
||||||
|
<el-select v-model="queryParams.month" placeholder="请选择时段" clearable class="w150"> |
||||||
|
<el-option v-for="dict in monthList" :key="dict.month" :label="dict.monthName" :value="dict.month" /> |
||||||
|
</el-select> |
||||||
|
</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;"> |
||||||
|
<div class="main-table-header"> |
||||||
|
<div class="table-title">{{tableTitle}}</div> |
||||||
|
<div class="table-time mb5"> |
||||||
|
<div> |
||||||
|
<span>测站编码: </span><span id="title2">{{staid}}</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<span>{{title}} </span><span id="title3" class="pl10">m= 85基准基准基面以上米数</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-table class="report-table merge-header" v-table-height="{bottom:130}" v-loading="loading" :data="tableData" style="width: 100%;" :table-layout="tableLayout" :span-method="arraySpanMethod"> |
||||||
|
<el-table-column prop="value" :align="alignment"> |
||||||
|
<el-table-column prop="date" width="40" :align="alignment" /> |
||||||
|
<el-table-column prop="yueTotal" width="90" :align="alignment" /> |
||||||
|
<template #header> |
||||||
|
<div class="diagonal-header"> |
||||||
|
<svg class="diagonal-line" viewBox="0 0 100 100" preserveAspectRatio="none"> |
||||||
|
<line x1="0" y1="0" x2="100" y2="100" stroke="#000" stroke-width="1" /> |
||||||
|
</svg> |
||||||
|
<div class="header-month">月份</div> |
||||||
|
<div class="header-date">日期</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column v-for="(item, index) in columnData" :key="index" :label="item.label" :align="alignment" :prop="item.prop"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="高潮" :align="alignment"> |
||||||
|
<el-table-column label='潮时' :align="alignment" /> |
||||||
|
<el-table-column label='潮高' :align="alignment" /> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="高潮" :align="alignment"> |
||||||
|
<el-table-column label='潮时' :align="alignment" /> |
||||||
|
<el-table-column label='潮高' :align="alignment" /> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="低潮" :align="alignment"> |
||||||
|
<el-table-column label='潮时' :align="alignment" /> |
||||||
|
<el-table-column label='潮高' :align="alignment" /> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="低潮" :align="alignment"> |
||||||
|
<el-table-column label='潮时' :align="alignment" /> |
||||||
|
<el-table-column label='潮高' :align="alignment" /> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="table-footer"> |
||||||
|
<div class="footer-item"> |
||||||
|
<span>制表:</span><span></span> |
||||||
|
<span></span><span>月</span> |
||||||
|
<span></span><span>日</span> |
||||||
|
</div> |
||||||
|
<div class="footer-item"> |
||||||
|
<span>初校:</span><span></span> |
||||||
|
<span></span><span>月</span> |
||||||
|
<span></span><span>日</span> |
||||||
|
</div> |
||||||
|
<div class="footer-item"> |
||||||
|
<span>复校:</span><span></span> |
||||||
|
<span></span><span>月</span> |
||||||
|
<span></span><span>日</span> |
||||||
|
</div> |
||||||
|
<div class="footer-item"> |
||||||
|
<span>审查:</span><span></span> |
||||||
|
<span></span><span>月</span> |
||||||
|
<span></span><span>日</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</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: '表格标题' |
||||||
|
}, |
||||||
|
|
||||||
|
}) |
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance() |
||||||
|
const alignment = 'center' |
||||||
|
const stationType = 'D' |
||||||
|
const tableLayout = ref('fixed') |
||||||
|
const singleStationRef = ref(null) |
||||||
|
// 新增处理站点变化的函数 |
||||||
|
const handleStationChange = (stnmId) => { |
||||||
|
queryParams.stnmId = stnmId |
||||||
|
if (stnmId == undefined) { |
||||||
|
proxy.$modal.msgWarning("请选择站点后查询"); |
||||||
|
return |
||||||
|
} else { |
||||||
|
loading.value = true; |
||||||
|
getList() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const loading = ref(false); |
||||||
|
const tableData = ref([]); |
||||||
|
const queryParams = reactive({ |
||||||
|
year: dayjs(new Date()).format('YYYY'), |
||||||
|
month: '01' |
||||||
|
}); |
||||||
|
const staid = ref('') |
||||||
|
const title = ref('') |
||||||
|
const getList = async () => { |
||||||
|
loading.value = true; |
||||||
|
try { |
||||||
|
const res = await proxy.axiosGet('/report/gettidehour', queryParams) |
||||||
|
if (res.code == 0) { |
||||||
|
staid.value = res.data.staid |
||||||
|
title.value = res.data.rTitle |
||||||
|
// let data = res.data |
||||||
|
let data = [] |
||||||
|
// 生成1~31日数据 |
||||||
|
for (let i = 1; i <= 31; i++) { |
||||||
|
let j = i - 1 |
||||||
|
data.push({ |
||||||
|
date: i, |
||||||
|
yueTotal: '', |
||||||
|
Jan: res.data.dayCountData[0][j] || '/', |
||||||
|
Feb: res.data.dayCountData[1][j] || '/', |
||||||
|
Mar: res.data.dayCountData[2][j] || '/', |
||||||
|
Apr: res.data.dayCountData[3][j] || '/', |
||||||
|
May: res.data.dayCountData[4][j] || '/', |
||||||
|
Jun: res.data.dayCountData[5][j] || '/', |
||||||
|
Jul: res.data.dayCountData[6][j] || '/', |
||||||
|
Aug: res.data.dayCountData[7][j] || '/', |
||||||
|
Sep: res.data.dayCountData[8][j] || '/', |
||||||
|
Oct: res.data.dayCountData[9][j] || '/', |
||||||
|
Nov: res.data.dayCountData[10][j] || '/', |
||||||
|
Dec: res.data.dayCountData[11][j] || '/' |
||||||
|
}) |
||||||
|
} |
||||||
|
let yueList = ['平均', '最高', '日期', '最低', '日期'] |
||||||
|
|
||||||
|
for (let i = 0; i < 5; i++) { |
||||||
|
data.push( |
||||||
|
{ |
||||||
|
yueTotal: yueList[i], |
||||||
|
date: "月统计", |
||||||
|
Jan: i == 0 ? res.data.avgList[0] : i == 1 ? res.data.maxList[0] : i == 2 ? res.data.maxDayList[0] : i == 3 ? res.data.minList[0] : i == 4 ? res.data.minDayList[0] : '/', |
||||||
|
Feb: i == 0 ? res.data.avgList[1] : i == 1 ? res.data.maxList[1] : i == 2 ? res.data.maxDayList[1] : i == 3 ? res.data.minList[1] : i == 4 ? res.data.minDayList[1] : '/', |
||||||
|
Mar: i == 0 ? res.data.avgList[2] : i == 1 ? res.data.maxList[2] : i == 2 ? res.data.maxDayList[2] : i == 3 ? res.data.minList[2] : i == 4 ? res.data.minDayList[2] : '/', |
||||||
|
Apr: i == 0 ? res.data.avgList[3] : i == 1 ? res.data.maxList[3] : i == 2 ? res.data.maxDayList[3] : i == 3 ? res.data.minList[3] : i == 4 ? res.data.minDayList[3] : '/', |
||||||
|
May: i == 0 ? res.data.avgList[4] : i == 1 ? res.data.maxList[4] : i == 2 ? res.data.maxDayList[4] : i == 3 ? res.data.minList[4] : i == 4 ? res.data.minDayList[4] : '/', |
||||||
|
Jun: i == 0 ? res.data.avgList[5] : i == 1 ? res.data.maxList[5] : i == 2 ? res.data.maxDayList[5] : i == 3 ? res.data.minList[5] : i == 4 ? res.data.minDayList[5] : '/', |
||||||
|
Jul: i == 0 ? res.data.avgList[6] : i == 1 ? res.data.maxList[6] : i == 2 ? res.data.maxDayList[6] : i == 3 ? res.data.minList[6] : i == 4 ? res.data.minDayList[6] : '/', |
||||||
|
Aug: i == 0 ? res.data.avgList[7] : i == 1 ? res.data.maxList[7] : i == 2 ? res.data.maxDayList[7] : i == 3 ? res.data.minList[7] : i == 4 ? res.data.minDayList[7] : '/', |
||||||
|
Sep: i == 0 ? res.data.avgList[8] : i == 1 ? res.data.maxList[8] : i == 2 ? res.data.maxDayList[8] : i == 3 ? res.data.minList[8] : i == 4 ? res.data.minDayList[8] : '/', |
||||||
|
Oct: i == 0 ? res.data.avgList[9] : i == 1 ? res.data.maxList[9] : i == 2 ? res.data.maxDayList[9] : i == 3 ? res.data.minList[9] : i == 4 ? res.data.minDayList[9] : '/', |
||||||
|
Nov: i == 0 ? res.data.avgList[10] : i == 1 ? res.data.maxList[10] : i == 2 ? res.data.maxDayList[10] : i == 3 ? res.data.minList[10] : i == 4 ? res.data.minDayList[10] : '/', |
||||||
|
Dec: i == 0 ? res.data.avgList[11] : i == 1 ? res.data.maxList[11] : i == 2 ? res.data.maxDayList[11] : i == 3 ? res.data.minList[11] : i == 4 ? res.data.minDayList[11] : '/' |
||||||
|
|
||||||
|
} |
||||||
|
) |
||||||
|
} |
||||||
|
let yearMaxValue = res.data.yearMax?.replace(/ /g, ' ').trim(); |
||||||
|
let yearMinValue = res.data.yearMin?.replace(/ /g, ' ').trim(); |
||||||
|
|
||||||
|
let nianList = ['最高水位', '保证率', '水位'] |
||||||
|
for (let i = 0; i < 3; i++) { |
||||||
|
data.push( |
||||||
|
{ |
||||||
|
date: "年统计", |
||||||
|
yueTotal: '', |
||||||
|
Jan: nianList[i], |
||||||
|
Feb: i == 0 ? yearMaxValue : i == 1 ? '最高' : i == 2 ? res.data.bz_max : '/', |
||||||
|
Mar: i == 0 ? '最低水位' : i == 1 ? '第15天' : i == 2 ? res.data.bz_15 : '/', |
||||||
|
Apr: i == 0 ? yearMinValue : i == 1 ? '第30天' : i == 2 ? res.data.bz_30 : '/', |
||||||
|
May: i == 0 ? '平均水位' : i == 1 ? '' : i == 2 ? '' : '/', |
||||||
|
Jun: i == 0 ? res.data.yearAvg : i == 1 ? '第90天' : i == 2 ? res.data.bz_90 : '/', |
||||||
|
Jul: '', |
||||||
|
Aug: i == 0 ? '' : i == 1 ? '第180天' : i == 2 ? res.data.bz_180 : '/', |
||||||
|
Sep: '', |
||||||
|
Oct: i == 0 ? '' : i == 1 ? '第270天' : i == 2 ? res.data.bz_270 : '/', |
||||||
|
Nov: '', |
||||||
|
Dec: i == 0 ? '' : i == 1 ? '最低' : i == 2 ? res.data.bz_min : '/', |
||||||
|
|
||||||
|
} |
||||||
|
) |
||||||
|
} |
||||||
|
// 添加附注行 |
||||||
|
data.push({ |
||||||
|
date: '附录', |
||||||
|
Jan: res.data.fuzhu |
||||||
|
}) |
||||||
|
tableData.value = data |
||||||
|
|
||||||
|
} |
||||||
|
console.log(tableData.value, 'tableData') |
||||||
|
loading.value = false |
||||||
|
} catch (error) { |
||||||
|
loading.value = false |
||||||
|
} |
||||||
|
} |
||||||
|
// 改变类型操作 |
||||||
|
const changeStationType = (val) => { |
||||||
|
queryParams.stationType = val |
||||||
|
queryParams.type = val == 'B' ? 1 : 0 |
||||||
|
} |
||||||
|
// 搜索按钮操作 |
||||||
|
const handleQuery = () => { |
||||||
|
getList() |
||||||
|
} |
||||||
|
// 重置按钮操作 |
||||||
|
const resetQuery = () => { } |
||||||
|
// 下载按钮操作 |
||||||
|
const handleExport = () => { } |
||||||
|
onMounted(() => { }) |
||||||
|
const columnData = ref([ |
||||||
|
{ label: '0', prop: '0' }, |
||||||
|
{ label: '1', prop: '1' }, |
||||||
|
{ label: '2', prop: '2 ' }, |
||||||
|
{ label: '3', prop: '3 ' }, |
||||||
|
{ label: '4', prop: '4 ' }, |
||||||
|
{ label: '5', prop: '5 ' }, |
||||||
|
{ label: '6', prop: '6 ' }, |
||||||
|
{ label: '7', prop: '7' }, |
||||||
|
{ label: '8', prop: '8' }, |
||||||
|
{ label: '9', prop: '9' }, |
||||||
|
{ label: '10', prop: '10' }, |
||||||
|
{ label: '11', prop: '11' }, |
||||||
|
{ label: '12', prop: '12' }, |
||||||
|
{ label: '13', prop: '13' }, |
||||||
|
{ label: '14', prop: '14' }, |
||||||
|
{ label: '15', prop: '15' }, |
||||||
|
{ label: '16', prop: '16' }, |
||||||
|
{ label: '17', prop: '17' }, |
||||||
|
{ label: '18', prop: '18' }, |
||||||
|
{ label: '19', prop: '19' }, |
||||||
|
{ label: '20', prop: '20' }, |
||||||
|
{ label: '21', prop: '21' }, |
||||||
|
{ label: '22', prop: '22' }, |
||||||
|
{ label: '23', prop: '23' }, |
||||||
|
{ label: '总计', prop: 'total' }, |
||||||
|
{ label: '平均', prop: 'avg' }, |
||||||
|
]) |
||||||
|
|
||||||
|
const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => { |
||||||
|
let rowList = [31, 32, 33, 34, 35, 36, 37, 38] |
||||||
|
// 表头行(第一行)合并第一列和第二列 |
||||||
|
if (!rowList.includes(rowIndex)) { |
||||||
|
if (columnIndex === 0) { |
||||||
|
// 第一列合并两列 |
||||||
|
return [1, 2]; |
||||||
|
} else if (columnIndex === 1) { |
||||||
|
// 第二列被合并,不显示 |
||||||
|
return [0, 0]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 月统计行合并 |
||||||
|
if (rowIndex >= 31 && rowIndex <= 35) { |
||||||
|
if (columnIndex === 0) { |
||||||
|
return rowIndex === 31 ? [5, 1] : [0, 0]; |
||||||
|
} |
||||||
|
if (columnIndex === 1) return [1, 1]; |
||||||
|
} |
||||||
|
|
||||||
|
// 年统计行合并 |
||||||
|
if (rowIndex >= 36 && rowIndex <= 38) { |
||||||
|
if (columnIndex === 0) { |
||||||
|
return rowIndex === 36 ? [3, 2] : [0, 0]; |
||||||
|
} |
||||||
|
|
||||||
|
if (columnIndex === 1) return [0, 0]; |
||||||
|
if (rowIndex == 36) { |
||||||
|
if (columnIndex === 2) { |
||||||
|
return [1, 1]; |
||||||
|
} else if (columnIndex === 3) { |
||||||
|
return [1, 3]; |
||||||
|
} else if (columnIndex === 4) { |
||||||
|
return [1, 1]; |
||||||
|
} else if (columnIndex === 5) { |
||||||
|
return [1, 3]; |
||||||
|
} else if (columnIndex === 6) { |
||||||
|
return [1, 1]; |
||||||
|
} else if (columnIndex === 7) { |
||||||
|
return [1, 3]; |
||||||
|
} else { |
||||||
|
return [0, 0]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
// 附录行合并 |
||||||
|
if (rowIndex === tableData.value.length - 1) { |
||||||
|
if (columnIndex === 1) { |
||||||
|
return [1, 2]; |
||||||
|
} else if (columnIndex === 2) { |
||||||
|
return [1, 12]; |
||||||
|
} else { |
||||||
|
return [0, 0]; |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
// 其他行不合并 |
||||||
|
return [1, 1]; |
||||||
|
} |
||||||
|
const monthList = [ |
||||||
|
{ month: "01", monthName: "1月" }, |
||||||
|
{ month: "02", monthName: "2月" }, |
||||||
|
{ month: "03", monthName: "3月" }, |
||||||
|
{ month: "04", monthName: "4月" }, |
||||||
|
{ month: "05", monthName: "5月" }, |
||||||
|
{ month: "06", monthName: "6月" }, |
||||||
|
{ month: "07", monthName: "7月" }, |
||||||
|
{ month: "08", monthName: "8月" }, |
||||||
|
{ month: "09", monthName: "9月" }, |
||||||
|
{ month: "10", monthName: "10月" }, |
||||||
|
{ month: "11", monthName: "11月" }, |
||||||
|
{ month: "12", monthName: "12月" }, |
||||||
|
] |
||||||
|
</script> |
||||||
|
<style scoped lang='scss'> |
||||||
|
.table-footer { |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
width: 90%; |
||||||
|
margin: 0 auto; |
||||||
|
|
||||||
|
.footer-item { |
||||||
|
width: 25%; |
||||||
|
margin-right: 20px; |
||||||
|
|
||||||
|
span:nth-child(1) { |
||||||
|
display: inline-block; |
||||||
|
width: 60%; |
||||||
|
} |
||||||
|
|
||||||
|
span:nth-child(4) { |
||||||
|
display: inline-block; |
||||||
|
width: 20%; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* 斜线表头容器 */ |
||||||
|
.diagonal-header { |
||||||
|
position: relative; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
min-height: 60px; |
||||||
|
/* 确保有足够空间 */ |
||||||
|
} |
||||||
|
|
||||||
|
/* SVG 斜线 */ |
||||||
|
.diagonal-line { |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
pointer-events: none; |
||||||
|
/* 防止遮挡点击事件 */ |
||||||
|
} |
||||||
|
|
||||||
|
/* 月份/日期文本样式 */ |
||||||
|
.header-month, |
||||||
|
.header-date { |
||||||
|
position: absolute; |
||||||
|
font-size: 12px; |
||||||
|
line-height: 1; |
||||||
|
z-index: 1; |
||||||
|
} |
||||||
|
|
||||||
|
/* 右上角月份 */ |
||||||
|
.header-month { |
||||||
|
top: 10%; |
||||||
|
right: 10%; |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
|
||||||
|
/* 左下角日期 */ |
||||||
|
.header-date { |
||||||
|
bottom: 10%; |
||||||
|
left: 10%; |
||||||
|
text-align: left; |
||||||
|
} |
||||||
|
|
||||||
|
/* 表头单元格高度调整 */ |
||||||
|
::v-deep .el-table__header th { |
||||||
|
padding: 0; |
||||||
|
height: 60px; |
||||||
|
/* 增加高度保证斜线效果 */ |
||||||
|
} |
||||||
|
|
||||||
|
::v-deep .el-table__header th.el-table__cell>.cell { |
||||||
|
padding: 0 !important; |
||||||
|
} |
||||||
|
|
||||||
|
/* 隐藏子列的表头行 */ |
||||||
|
.merge-header :deep(.el-table__header tr:nth-child(2)) { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
/* 隐藏前31行的下边框 */ |
||||||
|
::v-deep .el-table__body tr:nth-child(-n+30) td, |
||||||
|
::v-deep .el-table__body tr:nth-child(32) td, |
||||||
|
::v-deep .el-table__body tr:nth-child(33) td, |
||||||
|
::v-deep .el-table__body tr:nth-child(34) td, |
||||||
|
::v-deep .el-table__body tr:nth-child(35) td { |
||||||
|
border-bottom: none !important; |
||||||
|
} |
||||||
|
|
||||||
|
::v-deep .el-table__body tr:nth-child(32) td:nth-child(1) { |
||||||
|
border-bottom: 1px solid #000 !important; |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,340 @@ |
|||||||
|
<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="选择站点"> |
||||||
|
<singleStation ref="singleStationRef" :stationType="stationType" @stationChange="handleStationChange" /> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="年份"> |
||||||
|
<el-date-picker v-model="queryParams.year" type="year" value-format="YYYY" placeholder="选择年" :clearable="false"> |
||||||
|
</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 scroll-bar" style="max-width: 100%; overflow-x: hidden;"> |
||||||
|
<div class="main-table-header" style="width: 70%;margin:0 auto"> |
||||||
|
<div class="table-title">{{tableTitle}}</div> |
||||||
|
<div class="table-time mb5"> |
||||||
|
<div> |
||||||
|
<span>年份: </span><span id="title1">{{queryParams.year }}</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<span>测站编码: </span><span id="title2">{{staid}}</span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<span>{{title}} </span><span id="title3" class="pl10">m= 85基准基准基面以上米数</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-table class="report-table merge-header" v-loading="loading" :data="tableData" style="width: 70%;margin:0 auto" :table-layout="tableLayout" :span-method="arraySpanMethod"> |
||||||
|
<el-table-column prop="value" :align="alignment"> |
||||||
|
<el-table-column prop="date" width="40" :align="alignment" /> |
||||||
|
<el-table-column prop="yueTotal" width="90" :align="alignment" /> |
||||||
|
<template #header> |
||||||
|
<div class="diagonal-header"> |
||||||
|
<svg class="diagonal-line" viewBox="0 0 100 100" preserveAspectRatio="none"> |
||||||
|
<line x1="0" y1="0" x2="100" y2="100" stroke="#000" stroke-width="1" /> |
||||||
|
</svg> |
||||||
|
<div class="header-month">月份</div> |
||||||
|
<div class="header-date">日期</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
</el-table-column> |
||||||
|
<el-table-column v-for="(item, index) in columnData" :key="index" :label="item.label" :align="alignment" :prop="item.prop"> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<!-- <div> 备注:表格中 ' / '表示该日期整天缺测,其余缺测日期为部分缺测。 </div> --> |
||||||
|
</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: '表格标题' |
||||||
|
}, |
||||||
|
|
||||||
|
}) |
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance() |
||||||
|
const alignment = 'center' |
||||||
|
const stationType = 'D' |
||||||
|
const tableLayout = ref('fixed') |
||||||
|
const singleStationRef = ref(null) |
||||||
|
// 新增处理站点变化的函数 |
||||||
|
const handleStationChange = (stnmId) => { |
||||||
|
queryParams.stnmId = stnmId |
||||||
|
if (stnmId == undefined) { |
||||||
|
proxy.$modal.msgWarning("请选择站点后查询"); |
||||||
|
return |
||||||
|
} else { |
||||||
|
loading.value = true; |
||||||
|
getList() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const loading = ref(false); |
||||||
|
const tableData = ref([]); |
||||||
|
const queryParams = reactive({ |
||||||
|
year: dayjs(new Date()).format('YYYY'), |
||||||
|
type: 0 |
||||||
|
}); |
||||||
|
const staid = ref('') |
||||||
|
const title = ref('') |
||||||
|
const getList = async () => { |
||||||
|
loading.value = true; |
||||||
|
try { |
||||||
|
const res = await proxy.axiosGet('/report/zrtidedata', queryParams) |
||||||
|
if (res.code == 0) { |
||||||
|
staid.value = res.data.staid |
||||||
|
title.value = res.data.title |
||||||
|
// let data = res.data |
||||||
|
let data = [] |
||||||
|
// 生成1~31日数据 |
||||||
|
for (let i = 1; i <= 31; i++) { |
||||||
|
let j = i - 1 |
||||||
|
data.push({ |
||||||
|
date: i, |
||||||
|
yueTotal: '', |
||||||
|
Jan: res.data.dayCountData[0][j] || '/', |
||||||
|
Feb: res.data.dayCountData[1][j] || '/', |
||||||
|
Mar: res.data.dayCountData[2][j] || '/', |
||||||
|
Apr: res.data.dayCountData[3][j] || '/', |
||||||
|
May: res.data.dayCountData[4][j] || '/', |
||||||
|
Jun: res.data.dayCountData[5][j] || '/', |
||||||
|
Jul: res.data.dayCountData[6][j] || '/', |
||||||
|
Aug: res.data.dayCountData[7][j] || '/', |
||||||
|
Sep: res.data.dayCountData[8][j] || '/', |
||||||
|
Oct: res.data.dayCountData[9][j] || '/', |
||||||
|
Nov: res.data.dayCountData[10][j] || '/', |
||||||
|
Dec: res.data.dayCountData[11][j] || '/' |
||||||
|
}) |
||||||
|
} |
||||||
|
let yueList = ['平均', '最高', '日期', '最低', '日期'] |
||||||
|
|
||||||
|
for (let i = 0; i < 5; i++) { |
||||||
|
data.push( |
||||||
|
{ |
||||||
|
yueTotal: yueList[i], |
||||||
|
date: "月统计", |
||||||
|
Jan: i == 0 ? res.data.avgList[0] : i == 1 ? res.data.maxList[0] : i == 2 ? res.data.maxDayList[0] : i == 3 ? res.data.minList[0] : i == 4 ? res.data.minDayList[0] : '/', |
||||||
|
Feb: i == 0 ? res.data.avgList[1] : i == 1 ? res.data.maxList[1] : i == 2 ? res.data.maxDayList[1] : i == 3 ? res.data.minList[1] : i == 4 ? res.data.minDayList[1] : '/', |
||||||
|
Mar: i == 0 ? res.data.avgList[2] : i == 1 ? res.data.maxList[2] : i == 2 ? res.data.maxDayList[2] : i == 3 ? res.data.minList[2] : i == 4 ? res.data.minDayList[2] : '/', |
||||||
|
Apr: i == 0 ? res.data.avgList[3] : i == 1 ? res.data.maxList[3] : i == 2 ? res.data.maxDayList[3] : i == 3 ? res.data.minList[3] : i == 4 ? res.data.minDayList[3] : '/', |
||||||
|
May: i == 0 ? res.data.avgList[4] : i == 1 ? res.data.maxList[4] : i == 2 ? res.data.maxDayList[4] : i == 3 ? res.data.minList[4] : i == 4 ? res.data.minDayList[4] : '/', |
||||||
|
Jun: i == 0 ? res.data.avgList[5] : i == 1 ? res.data.maxList[5] : i == 2 ? res.data.maxDayList[5] : i == 3 ? res.data.minList[5] : i == 4 ? res.data.minDayList[5] : '/', |
||||||
|
Jul: i == 0 ? res.data.avgList[6] : i == 1 ? res.data.maxList[6] : i == 2 ? res.data.maxDayList[6] : i == 3 ? res.data.minList[6] : i == 4 ? res.data.minDayList[6] : '/', |
||||||
|
Aug: i == 0 ? res.data.avgList[7] : i == 1 ? res.data.maxList[7] : i == 2 ? res.data.maxDayList[7] : i == 3 ? res.data.minList[7] : i == 4 ? res.data.minDayList[7] : '/', |
||||||
|
Sep: i == 0 ? res.data.avgList[8] : i == 1 ? res.data.maxList[8] : i == 2 ? res.data.maxDayList[8] : i == 3 ? res.data.minList[8] : i == 4 ? res.data.minDayList[8] : '/', |
||||||
|
Oct: i == 0 ? res.data.avgList[9] : i == 1 ? res.data.maxList[9] : i == 2 ? res.data.maxDayList[9] : i == 3 ? res.data.minList[9] : i == 4 ? res.data.minDayList[9] : '/', |
||||||
|
Nov: i == 0 ? res.data.avgList[10] : i == 1 ? res.data.maxList[10] : i == 2 ? res.data.maxDayList[10] : i == 3 ? res.data.minList[10] : i == 4 ? res.data.minDayList[10] : '/', |
||||||
|
Dec: i == 0 ? res.data.avgList[11] : i == 1 ? res.data.maxList[11] : i == 2 ? res.data.maxDayList[11] : i == 3 ? res.data.minList[11] : i == 4 ? res.data.minDayList[11] : '/' |
||||||
|
|
||||||
|
} |
||||||
|
) |
||||||
|
} |
||||||
|
let yearMaxValue = res.data.yearMax?.replace(/ /g, ' ').trim(); |
||||||
|
let yearMinValue = res.data.yearMin?.replace(/ /g, ' ').trim(); |
||||||
|
let nianList = ['最高潮位'] |
||||||
|
for (let i = 0; i < 1; i++) { |
||||||
|
data.push( |
||||||
|
{ |
||||||
|
date: "年统计", |
||||||
|
yueTotal: '', |
||||||
|
Jan: nianList[i], |
||||||
|
Feb: i == 0 ? yearMaxValue : '/', |
||||||
|
Mar: i == 0 ? '最低潮位' : '/', |
||||||
|
Apr: i == 0 ? yearMinValue : '/', |
||||||
|
May: i == 0 ? '平均潮位' : '/', |
||||||
|
Jun: i == 0 ? res.data.yearAvg : '/', |
||||||
|
|
||||||
|
} |
||||||
|
) |
||||||
|
} |
||||||
|
// 添加附注行 |
||||||
|
data.push({ |
||||||
|
date: '附录', |
||||||
|
Jan: res.data.fuzhu |
||||||
|
}) |
||||||
|
tableData.value = data |
||||||
|
|
||||||
|
} |
||||||
|
console.log(tableData.value, 'tableData') |
||||||
|
loading.value = false |
||||||
|
} catch (error) { |
||||||
|
loading.value = false |
||||||
|
} |
||||||
|
} |
||||||
|
// 改变类型操作 |
||||||
|
const changeStationType = (val) => { |
||||||
|
queryParams.stationType = val |
||||||
|
queryParams.type = val == 'B' ? 1 : 0 |
||||||
|
} |
||||||
|
// 搜索按钮操作 |
||||||
|
const handleQuery = () => { |
||||||
|
getList() |
||||||
|
} |
||||||
|
// 重置按钮操作 |
||||||
|
const resetQuery = () => { } |
||||||
|
// 下载按钮操作 |
||||||
|
const handleExport = () => { } |
||||||
|
onMounted(() => { }) |
||||||
|
const columnData = ref([ |
||||||
|
{ label: '一月', prop: 'Jan' }, |
||||||
|
{ label: '二月', prop: 'Feb' }, |
||||||
|
{ label: '三月', prop: 'Mar' }, |
||||||
|
{ label: '四月', prop: 'Apr' }, |
||||||
|
{ label: '五月', prop: 'May' }, |
||||||
|
{ label: '六月', prop: 'Jun' }, |
||||||
|
{ label: '七月', prop: 'Jul' }, |
||||||
|
{ label: '八月', prop: 'Aug' }, |
||||||
|
{ label: '九月', prop: 'Sep' }, |
||||||
|
{ label: '十月', prop: 'Oct' }, |
||||||
|
{ label: '十一月', prop: 'Nov' }, |
||||||
|
{ label: '十二月', prop: 'Dec' } |
||||||
|
]) |
||||||
|
|
||||||
|
const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => { |
||||||
|
let rowList = [31, 32, 33, 34, 35, 36, 37, 38] |
||||||
|
// 表头行(第一行)合并第一列和第二列 |
||||||
|
if (!rowList.includes(rowIndex)) { |
||||||
|
if (columnIndex === 0) { |
||||||
|
// 第一列合并两列 |
||||||
|
return [1, 2]; |
||||||
|
} else if (columnIndex === 1) { |
||||||
|
// 第二列被合并,不显示 |
||||||
|
return [0, 0]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 月统计行合并 |
||||||
|
if (rowIndex >= 31 && rowIndex <= 35) { |
||||||
|
if (columnIndex === 0) { |
||||||
|
return rowIndex === 31 ? [5, 1] : [0, 0]; |
||||||
|
} |
||||||
|
if (columnIndex === 1) return [1, 1]; |
||||||
|
} |
||||||
|
|
||||||
|
// 年统计行合并 |
||||||
|
if (rowIndex >= 36 && rowIndex <= 38) { |
||||||
|
if (columnIndex === 0) { |
||||||
|
return rowIndex === 36 ? [3, 2] : [0, 0]; |
||||||
|
} |
||||||
|
|
||||||
|
if (columnIndex === 1) return [0, 0]; |
||||||
|
if (rowIndex == 36) { |
||||||
|
if (columnIndex === 2) { |
||||||
|
return [1, 1]; |
||||||
|
} else if (columnIndex === 3) { |
||||||
|
return [1, 3]; |
||||||
|
} else if (columnIndex === 4) { |
||||||
|
return [1, 1]; |
||||||
|
} else if (columnIndex === 5) { |
||||||
|
return [1, 3]; |
||||||
|
} else if (columnIndex === 6) { |
||||||
|
return [1, 1]; |
||||||
|
} else if (columnIndex === 7) { |
||||||
|
return [1, 3]; |
||||||
|
} else { |
||||||
|
return [0, 0]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
// 附录行合并 |
||||||
|
if (rowIndex === tableData.value.length - 1) { |
||||||
|
if (columnIndex === 1) { |
||||||
|
return [1, 2]; |
||||||
|
} else if (columnIndex === 2) { |
||||||
|
return [1, 12]; |
||||||
|
} else { |
||||||
|
return [0, 0]; |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
// 其他行不合并 |
||||||
|
return [1, 1]; |
||||||
|
} |
||||||
|
</script> |
||||||
|
<style scoped lang='scss'> |
||||||
|
/* 斜线表头容器 */ |
||||||
|
.diagonal-header { |
||||||
|
position: relative; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
min-height: 60px; |
||||||
|
/* 确保有足够空间 */ |
||||||
|
} |
||||||
|
|
||||||
|
/* SVG 斜线 */ |
||||||
|
.diagonal-line { |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
pointer-events: none; |
||||||
|
/* 防止遮挡点击事件 */ |
||||||
|
} |
||||||
|
|
||||||
|
/* 月份/日期文本样式 */ |
||||||
|
.header-month, |
||||||
|
.header-date { |
||||||
|
position: absolute; |
||||||
|
font-size: 12px; |
||||||
|
line-height: 1; |
||||||
|
z-index: 1; |
||||||
|
} |
||||||
|
|
||||||
|
/* 右上角月份 */ |
||||||
|
.header-month { |
||||||
|
top: 10%; |
||||||
|
right: 10%; |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
|
||||||
|
/* 左下角日期 */ |
||||||
|
.header-date { |
||||||
|
bottom: 10%; |
||||||
|
left: 10%; |
||||||
|
text-align: left; |
||||||
|
} |
||||||
|
|
||||||
|
/* 表头单元格高度调整 */ |
||||||
|
::v-deep .el-table__header th { |
||||||
|
padding: 0; |
||||||
|
height: 60px; |
||||||
|
/* 增加高度保证斜线效果 */ |
||||||
|
} |
||||||
|
|
||||||
|
::v-deep .el-table__header th.el-table__cell>.cell { |
||||||
|
padding: 0 !important; |
||||||
|
} |
||||||
|
|
||||||
|
/* 隐藏子列的表头行 */ |
||||||
|
.merge-header :deep(.el-table__header tr:nth-child(2)) { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
/* 隐藏前31行的下边框 */ |
||||||
|
::v-deep .el-table__body tr:nth-child(-n+30) td, |
||||||
|
::v-deep .el-table__body tr:nth-child(32) td, |
||||||
|
::v-deep .el-table__body tr:nth-child(33) td, |
||||||
|
::v-deep .el-table__body tr:nth-child(34) td, |
||||||
|
::v-deep .el-table__body tr:nth-child(35) td { |
||||||
|
border-bottom: none !important; |
||||||
|
} |
||||||
|
|
||||||
|
::v-deep .el-table__body tr:nth-child(32) td:nth-child(1) { |
||||||
|
border-bottom: 1px solid #000 !important; |
||||||
|
} |
||||||
|
</style> |
||||||
Loading…
Reference in new issue