2026-05-26 19:30:22 +08:00
|
|
|
|
<template>
|
2026-06-05 16:10:14 +08:00
|
|
|
|
<div class="monthly-average-container">
|
|
|
|
|
|
<!-- 搜索表单 -->
|
2026-06-08 15:34:13 +08:00
|
|
|
|
<a-form ref="formRef" :model="formValue" layout="inline" class="search-form">
|
2026-06-05 16:10:14 +08:00
|
|
|
|
<a-form-item label="基地名称" name="dataDimensionVal">
|
2026-06-08 15:34:13 +08:00
|
|
|
|
<a-select v-model:value="formValue.dataDimensionVal" placeholder="请选择" style="width: 200px"
|
|
|
|
|
|
@change="handleBaseChange">
|
2026-06-09 11:17:07 +08:00
|
|
|
|
<a-select-option v-for="item in jdList" :key="item.wbsCode" :value="item.wbsCode">
|
|
|
|
|
|
{{ item.wbsName }}
|
2026-06-05 16:10:14 +08:00
|
|
|
|
</a-select-option>
|
|
|
|
|
|
</a-select>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
|
|
|
|
|
|
<a-form-item label="所在流域" name="rvcd">
|
2026-06-08 15:34:13 +08:00
|
|
|
|
<a-select v-model:value="formValue.rvcd" placeholder="请选择" style="width: 200px"
|
|
|
|
|
|
:disabled="!formValue.dataDimensionVal" @change="handleRvcdChange">
|
|
|
|
|
|
<a-select-option v-for="item in lyList" :key="item.value" :value="item.value">
|
2026-06-05 16:10:14 +08:00
|
|
|
|
{{ item.label }}
|
|
|
|
|
|
</a-select-option>
|
|
|
|
|
|
</a-select>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
|
|
|
|
|
|
<a-form-item label="断面名称" name="stcd">
|
2026-06-08 15:34:13 +08:00
|
|
|
|
<a-select v-model:value="formValue.stcd" placeholder="请选择" style="width: 200px" :disabled="!formValue.rvcd">
|
|
|
|
|
|
<a-select-option v-for="item in dmList" :key="item.value" :value="item.value">
|
2026-06-05 16:10:14 +08:00
|
|
|
|
{{ item.label }}
|
|
|
|
|
|
</a-select-option>
|
|
|
|
|
|
</a-select>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
|
|
|
|
|
|
<a-form-item label="月份" name="tm">
|
2026-06-08 15:34:13 +08:00
|
|
|
|
<a-date-picker v-model:value="formValue.tm" picker="month" :disabled-date="disabledDate" format="YYYY-MM"
|
|
|
|
|
|
value-format="YYYY-MM-DD HH:mm:ss" :allow-clear="false" />
|
2026-06-05 16:10:14 +08:00
|
|
|
|
</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>
|
|
|
|
|
|
<div style="width: 100%; display: flex">
|
|
|
|
|
|
<!-- 图表容器:始终存在,不再使用 v-if -->
|
|
|
|
|
|
<div class="chart-wrapper" ref="chartRef"></div>
|
2026-06-08 15:34:13 +08:00
|
|
|
|
<BasicTable ref="tableRef" :scrollY="460" :columns="columns" :list-url="DetGetKendoListCust"
|
|
|
|
|
|
:search-params="{ sort: sort }" :transform-data="customTransform">
|
|
|
|
|
|
<template #action="{ record }">
|
|
|
|
|
|
<a @click="handleViewDetail(record)" class="text_hocer">查看详情</a>
|
2026-06-05 16:10:14 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
</BasicTable>
|
2026-05-26 19:30:22 +08:00
|
|
|
|
</div>
|
2026-06-05 16:10:14 +08:00
|
|
|
|
</div>
|
2026-05-26 19:30:22 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
2026-06-05 16:10:14 +08:00
|
|
|
|
import { ref, reactive, watch, onMounted, onBeforeUnmount } from 'vue';
|
|
|
|
|
|
import { message } from 'ant-design-vue';
|
|
|
|
|
|
import dayjs, { Dayjs } from 'dayjs';
|
|
|
|
|
|
import * as echarts from 'echarts';
|
|
|
|
|
|
import type { EChartsOption } from 'echarts';
|
|
|
|
|
|
import moment from 'moment';
|
|
|
|
|
|
import { omit } from 'lodash';
|
|
|
|
|
|
import { wbsbGetKendoList, getVmsstbprpt, DetGetKendoListCust } from '@/api/sw';
|
2026-05-26 19:30:22 +08:00
|
|
|
|
import BasicTable from '@/components/BasicTable/index.vue';
|
2026-06-05 16:10:14 +08:00
|
|
|
|
import { useModelStore } from '@/store/modules/model';
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
const modelStore = useModelStore();
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== Props 定义 ====================
|
|
|
|
|
|
interface Props {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
tm?: string;
|
|
|
|
|
|
dataDimensionVal?: string;
|
|
|
|
|
|
rvcd?: string;
|
|
|
|
|
|
stcd?: string;
|
|
|
|
|
|
jdList?: any[];
|
2026-05-26 19:30:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
tm: '',
|
|
|
|
|
|
dataDimensionVal: '',
|
|
|
|
|
|
rvcd: '',
|
|
|
|
|
|
stcd: '',
|
|
|
|
|
|
jdList: () => []
|
|
|
|
|
|
});
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
// ==================== 类型定义 ====================
|
|
|
|
|
|
interface DefautState {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
dataDimensionType: string;
|
|
|
|
|
|
dataDimensionVal: any;
|
|
|
|
|
|
tm: string | Dayjs;
|
|
|
|
|
|
startDt: string;
|
|
|
|
|
|
endDt: string;
|
|
|
|
|
|
stcd: string;
|
|
|
|
|
|
rvcd: string;
|
2026-05-26 19:30:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface OptionItem {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
label: string;
|
|
|
|
|
|
value: string;
|
2026-05-26 19:30:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== 响应式状态 ====================
|
2026-06-05 16:10:14 +08:00
|
|
|
|
const formRef = ref();
|
|
|
|
|
|
const chartRef = ref<HTMLElement | null>(null);
|
|
|
|
|
|
let chartInstance: echarts.ECharts | null = null;
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
2026-06-05 16:10:14 +08:00
|
|
|
|
const chartLoading = ref(false);
|
|
|
|
|
|
const tableLoading = ref(false);
|
|
|
|
|
|
const exportLoading = ref(false);
|
2026-05-26 19:30:22 +08:00
|
|
|
|
const tableRef = ref<any>(null);
|
|
|
|
|
|
|
|
|
|
|
|
const sort = [
|
2026-06-05 16:10:14 +08:00
|
|
|
|
{
|
|
|
|
|
|
field: 'dt',
|
|
|
|
|
|
dir: 'desc'
|
|
|
|
|
|
}
|
|
|
|
|
|
];
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
// 下拉列表
|
2026-06-05 16:10:14 +08:00
|
|
|
|
const lyList = ref<OptionItem[]>([]);
|
|
|
|
|
|
const dmList = ref<OptionItem[]>([]);
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
// 表单值
|
|
|
|
|
|
const formValue = reactive<DefautState>({
|
2026-06-05 16:10:14 +08:00
|
|
|
|
dataDimensionType: 'hyBase',
|
|
|
|
|
|
dataDimensionVal: props.dataDimensionVal || 'all',
|
|
|
|
|
|
tm: props.tm ? dayjs(props.tm) : dayjs(),
|
|
|
|
|
|
startDt: '',
|
|
|
|
|
|
endDt: '',
|
|
|
|
|
|
stcd: props.stcd || '',
|
|
|
|
|
|
rvcd: props.rvcd || ''
|
|
|
|
|
|
});
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
// 表格数据
|
2026-06-05 16:10:14 +08:00
|
|
|
|
const tableData = ref<any[]>([]);
|
2026-05-26 19:30:22 +08:00
|
|
|
|
const pagination = reactive({
|
2026-06-05 16:10:14 +08:00
|
|
|
|
current: 1,
|
|
|
|
|
|
pageSize: 20,
|
|
|
|
|
|
total: 0,
|
|
|
|
|
|
showSizeChanger: true,
|
|
|
|
|
|
showTotal: (total: number) => `共 ${total} 条`
|
|
|
|
|
|
});
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
// 图表数据
|
2026-06-05 16:10:14 +08:00
|
|
|
|
const optionData = ref<any[]>([]);
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
// ==================== 工具函数 ====================
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 单位转换
|
|
|
|
|
|
*/
|
|
|
|
|
|
const transUnit = (value: any, code: string, type: string): string => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
if (value === null || value === undefined) return '-';
|
|
|
|
|
|
const numValue = Number(value);
|
|
|
|
|
|
if (isNaN(numValue)) return '-';
|
|
|
|
|
|
return numValue.toFixed(2);
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取单位配置
|
|
|
|
|
|
*/
|
|
|
|
|
|
const getUnitConfigByCode = (code: string, type: string): { unit: string } => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
return { unit: '℃' };
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取颜色配置
|
|
|
|
|
|
*/
|
|
|
|
|
|
const getColorByCodeAndType = (code: string[], typeKey: string[]): string[] => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
// 实测值(蓝)、去年同期(紫)、天然(绿)
|
|
|
|
|
|
return ['#5470c6', '#9b59b6', '#91cc75'];
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 日期格式化
|
|
|
|
|
|
*/
|
2026-06-05 16:10:14 +08:00
|
|
|
|
const tmFmt = (d: string) => moment(d).format('YYYY-MM-DD');
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 格式化数值:保留一位小数,四舍五入,空值显示 -
|
|
|
|
|
|
*/
|
|
|
|
|
|
const formatNumber = (value: any): string => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
if (value === null || value === undefined || value === '') return '-';
|
|
|
|
|
|
const numValue = Number(value);
|
|
|
|
|
|
if (isNaN(numValue)) return '-';
|
|
|
|
|
|
return numValue.toFixed(1);
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 格式化日期为 YYYY-MM-DD 格式
|
|
|
|
|
|
*/
|
|
|
|
|
|
const formatDate = (dateStr: string): string => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
if (!dateStr) return '-';
|
|
|
|
|
|
try {
|
|
|
|
|
|
return dayjs(dateStr).format('YYYY-MM-DD');
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
return dateStr;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 计算变化趋势:实测值 - 去年同期值
|
|
|
|
|
|
*/
|
|
|
|
|
|
const calculateComparison = (record: any): string => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
const wt = record.wt;
|
|
|
|
|
|
const beforeWt = record.beforeWt;
|
|
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
|
wt === null ||
|
|
|
|
|
|
wt === undefined ||
|
|
|
|
|
|
wt === '' ||
|
|
|
|
|
|
beforeWt === null ||
|
|
|
|
|
|
beforeWt === undefined ||
|
|
|
|
|
|
beforeWt === ''
|
|
|
|
|
|
) {
|
|
|
|
|
|
return '-';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const wtNum = Number(wt);
|
|
|
|
|
|
const beforeWtNum = Number(beforeWt);
|
|
|
|
|
|
|
|
|
|
|
|
if (isNaN(wtNum) || isNaN(beforeWtNum)) return '-';
|
|
|
|
|
|
|
|
|
|
|
|
const diff = wtNum - beforeWtNum;
|
|
|
|
|
|
return diff.toFixed(1);
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 禁用未来日期
|
|
|
|
|
|
*/
|
|
|
|
|
|
const disabledDate = (current: Dayjs) => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
return current && current > dayjs().endOf('day');
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
// ==================== API 调用 ====================
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取流域下拉列表
|
|
|
|
|
|
*/
|
|
|
|
|
|
const fetchLyData = async () => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
try {
|
|
|
|
|
|
console.log('获取流域列表,baseid:', formValue.dataDimensionVal);
|
|
|
|
|
|
let params = {
|
|
|
|
|
|
filter: {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: [
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'wbsType',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
value: 'PSB_RVCD'
|
|
|
|
|
|
},
|
|
|
|
|
|
formValue.dataDimensionVal != 'all'
|
|
|
|
|
|
? {
|
2026-06-08 15:34:13 +08:00
|
|
|
|
field: 'fullPath',
|
|
|
|
|
|
operator: 'startswith',
|
|
|
|
|
|
value: formValue.dataDimensionVal
|
|
|
|
|
|
}
|
2026-06-05 16:10:14 +08:00
|
|
|
|
: null
|
|
|
|
|
|
].filter(Boolean)
|
|
|
|
|
|
},
|
|
|
|
|
|
group: [
|
|
|
|
|
|
{ dir: 'asc', field: 'orderIndex' },
|
|
|
|
|
|
{ dir: 'asc', field: 'wbsCode' },
|
|
|
|
|
|
{ dir: 'asc', field: 'wbsName' },
|
|
|
|
|
|
{ dir: 'asc', field: 'objid' }
|
|
|
|
|
|
],
|
|
|
|
|
|
groupResultFlat: true
|
|
|
|
|
|
};
|
|
|
|
|
|
const res = await wbsbGetKendoList(params);
|
|
|
|
|
|
let data = res?.data?.data || res?.data || [];
|
|
|
|
|
|
if (data.length > 0) {
|
|
|
|
|
|
const options = data.map((item: any) => ({
|
|
|
|
|
|
label: item.wbsName,
|
|
|
|
|
|
value: item.wbsCode
|
|
|
|
|
|
}));
|
|
|
|
|
|
lyList.value = options;
|
|
|
|
|
|
const rvcd =
|
|
|
|
|
|
options.find((i: any) => i.value === props.rvcd)?.value ||
|
|
|
|
|
|
options[0]?.value;
|
|
|
|
|
|
formValue.rvcd = rvcd;
|
|
|
|
|
|
await fetchDmData();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
lyList.value = [];
|
|
|
|
|
|
formValue.rvcd = '';
|
|
|
|
|
|
await fetchDmData();
|
2026-05-26 19:30:22 +08:00
|
|
|
|
}
|
2026-06-05 16:10:14 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
// 忽略错误
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取断面下拉列表
|
|
|
|
|
|
*/
|
|
|
|
|
|
const fetchDmData = async () => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
try {
|
|
|
|
|
|
console.log(
|
|
|
|
|
|
'获取断面列表,baseid:',
|
|
|
|
|
|
formValue.dataDimensionVal,
|
|
|
|
|
|
'rvcd:',
|
|
|
|
|
|
formValue.rvcd
|
|
|
|
|
|
);
|
|
|
|
|
|
let params = {
|
|
|
|
|
|
filter: {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: [
|
|
|
|
|
|
{ field: 'sttpCode', operator: 'eq', value: 'WTRV' },
|
|
|
|
|
|
{ field: 'mway', operator: 'eq', value: 2 },
|
|
|
|
|
|
formValue.dataDimensionVal == 'all'
|
|
|
|
|
|
? {
|
2026-06-08 15:34:13 +08:00
|
|
|
|
field: 'rvcd',
|
|
|
|
|
|
operator: 'contains',
|
|
|
|
|
|
value: formValue.rvcd
|
|
|
|
|
|
}
|
2026-06-05 16:10:14 +08:00
|
|
|
|
: {
|
2026-06-08 15:34:13 +08:00
|
|
|
|
field: 'baseId',
|
|
|
|
|
|
operator: 'contains',
|
|
|
|
|
|
value: formValue.dataDimensionVal
|
|
|
|
|
|
}
|
2026-06-05 16:10:14 +08:00
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
select: ['stcd', 'stnm', 'lgtd', 'lttd', 'rstcdStepSort'],
|
|
|
|
|
|
sort: [{ field: 'rstcdStepSort', dir: 'desc' }]
|
|
|
|
|
|
};
|
|
|
|
|
|
const res = await getVmsstbprpt(params);
|
|
|
|
|
|
let resData = res?.data?.data || res?.data || [];
|
|
|
|
|
|
const options = resData.map((item: any) => ({
|
|
|
|
|
|
label: item.stnm,
|
|
|
|
|
|
value: item.stcd
|
|
|
|
|
|
}));
|
|
|
|
|
|
dmList.value = options;
|
|
|
|
|
|
const stcd =
|
|
|
|
|
|
options.find((i: any) => i.value === props.stcd)?.value ||
|
|
|
|
|
|
options[0]?.value;
|
|
|
|
|
|
formValue.stcd = stcd || '';
|
|
|
|
|
|
handleSearch();
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取断面列表失败:', error);
|
|
|
|
|
|
message.error('获取断面列表失败');
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取图表数据
|
|
|
|
|
|
*/
|
|
|
|
|
|
const getChartData = async (value: any) => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
// 显示 loading
|
|
|
|
|
|
if (chartInstance) {
|
|
|
|
|
|
chartInstance.showLoading('default', {
|
|
|
|
|
|
text: '加载中...',
|
|
|
|
|
|
color: '#5470c6',
|
|
|
|
|
|
textColor: '#000',
|
|
|
|
|
|
maskColor: 'rgba(255, 255, 255, 0.8)',
|
|
|
|
|
|
zlevel: 0
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
chartLoading.value = true;
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const tmValue = dayjs.isDayjs(value.tm) ? value.tm : dayjs(value.tm);
|
|
|
|
|
|
|
|
|
|
|
|
let params = {
|
|
|
|
|
|
filter: {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: [
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'stcd',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: value.stcd
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'startTime',
|
|
|
|
|
|
operator: 'gte',
|
|
|
|
|
|
dataType: 'date',
|
|
|
|
|
|
value: tmValue.startOf('month').format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'endTime',
|
|
|
|
|
|
operator: 'lte',
|
|
|
|
|
|
dataType: 'date',
|
|
|
|
|
|
value: tmValue.endOf('month').format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
const res = await DetGetKendoListCust(params);
|
|
|
|
|
|
let data = res?.data?.data || res?.data || [];
|
|
|
|
|
|
|
|
|
|
|
|
if (data.length > 0) {
|
|
|
|
|
|
optionData.value = data;
|
|
|
|
|
|
updateChart(); // 正常绘制图表
|
|
|
|
|
|
} else {
|
|
|
|
|
|
optionData.value = [];
|
|
|
|
|
|
// 数据为空:清除图表并显示“暂无数据”
|
|
|
|
|
|
if (chartInstance) {
|
|
|
|
|
|
chartInstance.clear();
|
|
|
|
|
|
chartInstance.setOption({
|
|
|
|
|
|
title: {
|
|
|
|
|
|
show: true,
|
|
|
|
|
|
text: '暂无数据',
|
|
|
|
|
|
left: 'center',
|
|
|
|
|
|
top: 'center',
|
|
|
|
|
|
textStyle: {
|
|
|
|
|
|
color: '#999',
|
|
|
|
|
|
fontSize: 14
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-05-26 19:30:22 +08:00
|
|
|
|
});
|
2026-06-05 16:10:14 +08:00
|
|
|
|
}
|
2026-05-26 19:30:22 +08:00
|
|
|
|
}
|
2026-06-05 16:10:14 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取图表数据失败:', error);
|
|
|
|
|
|
message.error('获取图表数据失败');
|
|
|
|
|
|
if (chartInstance) {
|
|
|
|
|
|
chartInstance.clear();
|
|
|
|
|
|
chartInstance.setOption({
|
|
|
|
|
|
title: {
|
|
|
|
|
|
show: true,
|
|
|
|
|
|
text: '数据加载失败',
|
|
|
|
|
|
left: 'center',
|
|
|
|
|
|
top: 'center',
|
|
|
|
|
|
textStyle: { color: '#f00' }
|
2026-05-26 19:30:22 +08:00
|
|
|
|
}
|
2026-06-05 16:10:14 +08:00
|
|
|
|
});
|
2026-05-26 19:30:22 +08:00
|
|
|
|
}
|
2026-06-05 16:10:14 +08:00
|
|
|
|
} finally {
|
|
|
|
|
|
chartLoading.value = false;
|
|
|
|
|
|
if (chartInstance) {
|
|
|
|
|
|
chartInstance.hideLoading();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取表格数据
|
|
|
|
|
|
*/
|
|
|
|
|
|
const getTableData = async (value: any) => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
try {
|
|
|
|
|
|
const tmValue = dayjs.isDayjs(value.tm) ? value.tm : dayjs(value.tm);
|
|
|
|
|
|
const filter = {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: [
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'stcd',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: value.stcd
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'startTime',
|
|
|
|
|
|
operator: 'gte',
|
|
|
|
|
|
dataType: 'date',
|
|
|
|
|
|
value: tmValue.startOf('month').format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'endTime',
|
|
|
|
|
|
operator: 'lte',
|
|
|
|
|
|
dataType: 'date',
|
|
|
|
|
|
value: tmValue.endOf('month').format('YYYY-MM-DD HH:mm:ss')
|
2026-05-26 19:30:22 +08:00
|
|
|
|
}
|
2026-06-05 16:10:14 +08:00
|
|
|
|
]
|
|
|
|
|
|
};
|
|
|
|
|
|
tableRef.value?.getList(filter);
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
// 忽略错误
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
// ==================== 图表相关 ====================
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 初始化图表
|
|
|
|
|
|
*/
|
|
|
|
|
|
const initChart = () => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
if (!chartRef.value) return;
|
|
|
|
|
|
chartInstance = echarts.init(chartRef.value);
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 更新图表(有数据时调用)
|
|
|
|
|
|
*/
|
|
|
|
|
|
const updateChart = () => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
if (!chartInstance) return;
|
|
|
|
|
|
|
|
|
|
|
|
// 清除可能残留的“暂无数据”title
|
|
|
|
|
|
chartInstance.setOption({ title: { show: false } }, false);
|
|
|
|
|
|
|
|
|
|
|
|
const { unit } = getUnitConfigByCode('Other', 'ACTUALTEMP');
|
|
|
|
|
|
const legendData = ['实测值', '去年同期', '天然'];
|
|
|
|
|
|
|
|
|
|
|
|
const xData: any[] = [];
|
|
|
|
|
|
const actualData: (number | null)[] = [];
|
|
|
|
|
|
const lastData: (number | null)[] = [];
|
|
|
|
|
|
const naturalData: (number | null)[] = [];
|
|
|
|
|
|
|
|
|
|
|
|
optionData.value.forEach((item: any) => {
|
|
|
|
|
|
actualData.push(
|
|
|
|
|
|
item.wt === null
|
|
|
|
|
|
? null
|
|
|
|
|
|
: Number(transUnit(item.wt, 'Other', 'ACTUALTEMP'))
|
|
|
|
|
|
);
|
|
|
|
|
|
lastData.push(
|
|
|
|
|
|
item.beforeWt === null
|
|
|
|
|
|
? null
|
|
|
|
|
|
: Number(transUnit(item.beforeWt, 'Other', 'LASTTEMP'))
|
|
|
|
|
|
);
|
|
|
|
|
|
naturalData.push(
|
|
|
|
|
|
item.actualTemp === null
|
|
|
|
|
|
? null
|
|
|
|
|
|
: Number(transUnit(item.actualTemp, 'Other', 'NATURALTEMP'))
|
|
|
|
|
|
);
|
|
|
|
|
|
xData.push({ value: item.dt });
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const code = ['Other'];
|
|
|
|
|
|
const typeKey = ['ACTUALTEMP', 'LASTTEMP', 'NATURALTEMP'];
|
|
|
|
|
|
const colors = getColorByCodeAndType(code, typeKey);
|
|
|
|
|
|
|
|
|
|
|
|
const option: EChartsOption = {
|
|
|
|
|
|
color: colors,
|
|
|
|
|
|
tooltip: {
|
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
|
formatter: (params: any) => {
|
|
|
|
|
|
const a = params
|
|
|
|
|
|
.map((item: any) => {
|
|
|
|
|
|
const value =
|
|
|
|
|
|
item.value !== null && item.value !== undefined
|
|
|
|
|
|
? item.value
|
|
|
|
|
|
: '-';
|
|
|
|
|
|
return `<div>${item.marker}${item.seriesName}: <span style="float:right">${value} ${unit}</span></div>`;
|
|
|
|
|
|
})
|
|
|
|
|
|
.join('');
|
|
|
|
|
|
return `<h3 style="color:#FFF">${tmFmt(params[0].name)}</h3>${a}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
legend: {
|
|
|
|
|
|
data: legendData
|
|
|
|
|
|
},
|
|
|
|
|
|
xAxis: {
|
|
|
|
|
|
type: 'category',
|
|
|
|
|
|
boundaryGap: false,
|
|
|
|
|
|
axisTick: { show: true },
|
|
|
|
|
|
data: xData,
|
|
|
|
|
|
axisLabel: {
|
|
|
|
|
|
formatter: (value: string) => tmFmt(value)
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
yAxis: {
|
|
|
|
|
|
type: 'value',
|
|
|
|
|
|
name: `水温(${unit})`,
|
|
|
|
|
|
scale: true,
|
|
|
|
|
|
axisLine: { show: true }
|
|
|
|
|
|
},
|
|
|
|
|
|
dataZoom: [
|
|
|
|
|
|
{
|
|
|
|
|
|
type: 'inside',
|
|
|
|
|
|
show: false,
|
|
|
|
|
|
xAxisIndex: [0],
|
|
|
|
|
|
yAxisIndex: [], // 不控制 Y 轴缩放
|
|
|
|
|
|
zoomOnMouseWheel: true,
|
|
|
|
|
|
moveOnMouseMove: true
|
|
|
|
|
|
}
|
|
|
|
|
|
],
|
|
|
|
|
|
series: [
|
|
|
|
|
|
{
|
|
|
|
|
|
name: legendData[0],
|
|
|
|
|
|
data: actualData,
|
|
|
|
|
|
type: 'line',
|
|
|
|
|
|
connectNulls: true,
|
|
|
|
|
|
smooth: true
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: legendData[1],
|
|
|
|
|
|
data: lastData,
|
|
|
|
|
|
type: 'line',
|
|
|
|
|
|
connectNulls: true,
|
|
|
|
|
|
smooth: true
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
name: legendData[2],
|
|
|
|
|
|
data: naturalData,
|
|
|
|
|
|
type: 'line',
|
|
|
|
|
|
connectNulls: true,
|
|
|
|
|
|
smooth: true
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
chartInstance.setOption(option, true); // notMerge = true 确保完全替换
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('图表更新失败:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
// ==================== 事件处理 ====================
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 基地变化
|
|
|
|
|
|
*/
|
|
|
|
|
|
const handleBaseChange = async (value: string) => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
formValue.dataDimensionVal = value;
|
|
|
|
|
|
formValue.rvcd = '';
|
|
|
|
|
|
formValue.stcd = '';
|
|
|
|
|
|
lyList.value = [];
|
|
|
|
|
|
dmList.value = [];
|
|
|
|
|
|
await fetchLyData();
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 流域变化
|
|
|
|
|
|
*/
|
|
|
|
|
|
const handleRvcdChange = async (value: string) => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
formValue.rvcd = value;
|
|
|
|
|
|
formValue.stcd = '';
|
|
|
|
|
|
dmList.value = [];
|
|
|
|
|
|
await fetchDmData();
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 搜索
|
|
|
|
|
|
*/
|
|
|
|
|
|
const handleSearch = async () => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
// if (!formValue.stcd) {
|
|
|
|
|
|
// message.error('请选择断面名称')
|
|
|
|
|
|
// return
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
const tmValue = dayjs.isDayjs(formValue.tm)
|
|
|
|
|
|
? formValue.tm.format('YYYY-MM-DD 00:00:00')
|
|
|
|
|
|
: moment(formValue.tm).format('YYYY-MM-DD 00:00:00');
|
|
|
|
|
|
|
|
|
|
|
|
const values = {
|
|
|
|
|
|
...formValue,
|
|
|
|
|
|
tm: tmValue
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
await getChartData(values);
|
|
|
|
|
|
await getTableData(values);
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 导出
|
|
|
|
|
|
*/
|
|
|
|
|
|
const handleExport = async () => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
exportLoading.value = true;
|
|
|
|
|
|
try {
|
|
|
|
|
|
const tmValue = dayjs.isDayjs(formValue.tm)
|
|
|
|
|
|
? formValue.tm.format('YYYY-MM-DD 00:00:00')
|
|
|
|
|
|
: moment(formValue.tm).format('YYYY-MM-DD 00:00:00');
|
|
|
|
|
|
|
|
|
|
|
|
const params = {
|
|
|
|
|
|
...buildFilterParams({ ...formValue, tm: tmValue }),
|
|
|
|
|
|
exportType: 'excel',
|
|
|
|
|
|
exportFileName: `月平均水温历史对比 ${moment().format(
|
|
|
|
|
|
'YYYY-MM-DD HH-mm-ss'
|
|
|
|
|
|
)}`
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
2026-06-05 16:10:14 +08:00
|
|
|
|
message.success('导出功能待实现');
|
|
|
|
|
|
console.log('导出参数:', params);
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('导出失败:', error);
|
|
|
|
|
|
message.error('导出失败');
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
exportLoading.value = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 表格分页变化
|
|
|
|
|
|
*/
|
|
|
|
|
|
const handleTableChange = (pag: any) => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
pagination.current = pag.current;
|
|
|
|
|
|
pagination.pageSize = pag.pageSize;
|
|
|
|
|
|
handleSearch();
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 构建表格过滤参数
|
|
|
|
|
|
*/
|
|
|
|
|
|
const buildFilterParams = (values: any) => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
let _p: any = { ...values, stcd: values?.stcd || props?.stcd };
|
|
|
|
|
|
|
|
|
|
|
|
if (_p.tm) {
|
|
|
|
|
|
const tmValue = dayjs.isDayjs(_p.tm) ? _p.tm : dayjs(_p.tm);
|
|
|
|
|
|
_p.startDt = [
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'startTime',
|
|
|
|
|
|
operator: 'gte',
|
|
|
|
|
|
dataType: 'date',
|
|
|
|
|
|
value: tmValue.startOf('month').format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
|
|
}
|
|
|
|
|
|
];
|
|
|
|
|
|
_p.endDt = [
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'endTime',
|
|
|
|
|
|
operator: 'lte',
|
|
|
|
|
|
dataType: 'date',
|
|
|
|
|
|
value: tmValue.endOf('month').format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
|
|
}
|
|
|
|
|
|
];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!_p?.stcd) {
|
|
|
|
|
|
_p.stcd = '';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return omit(_p, ['dataDimensionType', 'dataDimensionVal', 'tm', 'rvcd']);
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
// ==================== 表格列配置 ====================
|
|
|
|
|
|
|
2026-06-05 16:10:14 +08:00
|
|
|
|
const { unit } = getUnitConfigByCode('Other', 'ACTUALTEMP');
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
const columns = [
|
2026-06-05 16:10:14 +08:00
|
|
|
|
{
|
|
|
|
|
|
title: '日期',
|
|
|
|
|
|
dataIndex: 'dt',
|
|
|
|
|
|
key: 'dt',
|
|
|
|
|
|
width: 120,
|
|
|
|
|
|
customRender: ({ record }: any) => formatDate(record.dt)
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '日均水温(℃)实测值',
|
|
|
|
|
|
dataIndex: 'wt',
|
|
|
|
|
|
key: 'wt',
|
|
|
|
|
|
width: 150,
|
|
|
|
|
|
customRender: ({ record }: any) => formatNumber(record.wt)
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '日均水温(℃)去年同期',
|
|
|
|
|
|
dataIndex: 'beforeWt',
|
|
|
|
|
|
key: 'beforeWt',
|
|
|
|
|
|
width: 150,
|
|
|
|
|
|
customRender: ({ record }: any) => formatNumber(record.beforeWt)
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '天然值',
|
|
|
|
|
|
dataIndex: 'actualTemp',
|
|
|
|
|
|
key: 'actualTemp',
|
|
|
|
|
|
width: 120,
|
|
|
|
|
|
customRender: ({ record }: any) => formatNumber(record.actualTemp)
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: `变化趋势(${unit})`,
|
|
|
|
|
|
key: 'comparison',
|
|
|
|
|
|
width: 150,
|
|
|
|
|
|
customRender: ({ record }: any) => calculateComparison(record)
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '操作',
|
|
|
|
|
|
key: 'action',
|
|
|
|
|
|
width: 100,
|
|
|
|
|
|
align: 'center' as const,
|
2026-06-08 15:34:13 +08:00
|
|
|
|
fixed: 'right' as const,
|
|
|
|
|
|
slots: { customRender: 'action' }
|
2026-06-05 16:10:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
];
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
// ==================== 监听器 ====================
|
|
|
|
|
|
|
|
|
|
|
|
watch(
|
2026-06-05 16:10:14 +08:00
|
|
|
|
() => [props.tm, props.dataDimensionVal, props.rvcd, props.stcd],
|
|
|
|
|
|
() => {
|
|
|
|
|
|
if (props.tm) formValue.tm = dayjs(props.tm);
|
|
|
|
|
|
if (props.dataDimensionVal)
|
|
|
|
|
|
formValue.dataDimensionVal = props.dataDimensionVal;
|
|
|
|
|
|
if (props.rvcd) formValue.rvcd = props.rvcd;
|
|
|
|
|
|
if (props.stcd) formValue.stcd = props.stcd;
|
|
|
|
|
|
},
|
|
|
|
|
|
{ deep: true }
|
|
|
|
|
|
);
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
// ==================== 生命周期 ====================
|
|
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
initChart();
|
|
|
|
|
|
}, 100);
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
2026-06-05 16:10:14 +08:00
|
|
|
|
fetchLyData();
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
2026-06-05 16:10:14 +08:00
|
|
|
|
window.addEventListener('resize', handleResize);
|
|
|
|
|
|
});
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
onBeforeUnmount(() => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
window.removeEventListener('resize', handleResize);
|
|
|
|
|
|
chartInstance?.dispose();
|
|
|
|
|
|
});
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
// ==================== 工具方法 ====================
|
|
|
|
|
|
|
|
|
|
|
|
const handleResize = () => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
chartInstance?.resize();
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
const customTransform = (res: any) => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
console.log('表格数据:', res);
|
|
|
|
|
|
return {
|
|
|
|
|
|
records: res?.data?.data || [],
|
|
|
|
|
|
total: res?.data?.total || 0
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleViewDetail = (record: any) => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
let stnm = record.stnm;
|
|
|
|
|
|
dmList.value.forEach((element: any) => {
|
|
|
|
|
|
if (element.value == formValue.stcd) {
|
|
|
|
|
|
stnm = element.label;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
modelStore.modalVisible = true;
|
2026-06-08 15:34:13 +08:00
|
|
|
|
modelStore.params.sttp = 'WT';
|
2026-06-05 16:10:14 +08:00
|
|
|
|
modelStore.title = stnm + '详情信息';
|
|
|
|
|
|
modelStore.params.stcd = formValue.stcd;
|
|
|
|
|
|
};
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
|
|
|
|
|
defineExpose({
|
2026-06-05 16:10:14 +08:00
|
|
|
|
handleSearch,
|
|
|
|
|
|
getChartData,
|
|
|
|
|
|
getTableData
|
|
|
|
|
|
});
|
2026-05-26 19:30:22 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
|
.monthly-average-container {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
width: 100%;
|
|
|
|
|
|
/* padding: 16px; */
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
2026-06-05 16:10:14 +08:00
|
|
|
|
.search-form {
|
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
|
/* padding: 16px; */
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chart-wrapper {
|
|
|
|
|
|
width: 40%;
|
|
|
|
|
|
height: 600px;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
/* padding: 16px; */
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
}
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
2026-06-05 16:10:14 +08:00
|
|
|
|
.table-wrapper {
|
|
|
|
|
|
flex: 7;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
/* padding: 16px; */
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
}
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
2026-06-05 16:10:14 +08:00
|
|
|
|
.text_hocer {
|
|
|
|
|
|
color: #2f6b98;
|
2026-05-26 19:30:22 +08:00
|
|
|
|
|
2026-06-05 16:10:14 +08:00
|
|
|
|
&:hover {
|
|
|
|
|
|
color: #40a9ff;
|
2026-05-26 19:30:22 +08:00
|
|
|
|
}
|
2026-06-05 16:10:14 +08:00
|
|
|
|
}
|
2026-05-26 19:30:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
:deep(.ant-spin-nested-loading) {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
width: 100%;
|
2026-05-26 19:30:22 +08:00
|
|
|
|
}
|
2026-06-05 16:10:14 +08:00
|
|
|
|
</style>
|