WholeProcessPlatform/frontend/src/modules/shuishengtaidiaochaduanmian/index.vue
2026-08-20 16:55:09 +08:00

320 lines
7.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- SidePanelItem.vue -->
<template>
<SidePanelItem :title="title" @update-values="handlePanelChange">
<div ref="chartRef" class="chart-container"></div>
</SidePanelItem>
<!-- 水生生态调查概况弹框 -->
<a-modal
v-model:open="modalVisible"
title="水生生态调查概况"
width="1536px"
:footer="null"
@cancel="handleModalClose"
>
<SsstdcgkTk
v-if="modalVisible"
:selectDateTime="datetimePicker.value"
:all="true"
/>
</a-modal>
</template>
<script lang="ts" setup>
import {
ref,
watch,
inject,
defineOptions,
computed,
onMounted,
onBeforeUnmount,
nextTick
} from 'vue';
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
import SidePanelItem from '@/components/SidePanelItem/index.vue';
import SsstdcgkTk from './SsstdcgkTk.vue';
import { wbsbGetKendoList, getDftYear } from '@/api/stdc';
import moment from 'moment';
import { Label } from 'cesium';
import { useDraggable } from '@/utils/drag';
import * as echarts from 'echarts';
// 定义组件名
defineOptions({
name: 'shuishengshengtaijiance'
});
const title = ref('水生态生态调查断面 (23)个');
const JidiSelectEventStore = useJidiSelectEventStore();
const baseid = ref('');
// ==================== 弹框状态 ====================
const modalVisible = ref(false);
useDraggable(modalVisible, { boundary: true, resetOnOpen: true });
// ==================== 响应式变量定义 ====================
// 选择器配置
const select = ref({
show: true,
value: undefined,
options: [],
picker: undefined,
format: undefined,
width: '120px'
});
// 日期选择器配置
const datetimePicker = ref({
show: true,
value: '',
format: 'YYYY',
picker: 'year' as const,
options: []
});
// ==================== 图表(柱状图) ====================
const chartRef = ref<HTMLElement>();
let chartInstance: echarts.ECharts | null = null;
let resizeObserver: ResizeObserver | null = null;
// 柱状图数据(先写死,后续接入接口)
const chartData = [
{ name: '长江流域', value: 5 },
{ name: '黄河流域', value: 8 }
];
// 渲染柱状图
const renderChart = () => {
if (!chartInstance) return;
chartInstance.setOption(
{
legend: {
data: ['数量'],
top: '0',
left: 'center',
textStyle: { fontSize: 12, color: '#666' }
},
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' },
backgroundColor: 'rgba(50, 50, 50, 0.9)',
borderColor: 'transparent',
textStyle: { color: '#fff', fontSize: 12 }
},
grid: { left: 40, right: 20, top: 40, bottom: 30 },
xAxis: {
type: 'category',
data: chartData.map(item => item.name),
axisLine: { lineStyle: { color: '#000000' } },
axisTick: { show: false },
axisLabel: { fontSize: 12 }
},
yAxis: {
type: 'value',
axisLine: { lineStyle: { color: '#000000' } },
splitLine: { lineStyle: { color: '#bfbfbf', type: 'solid' } },
axisLabel: { fontSize: 12 }
},
series: [
{
name: '数量',
type: 'bar',
data: chartData.map(item => item.value),
barWidth: 30,
itemStyle: { color: '#6395FA', borderRadius: [4, 4, 0, 0] }
}
]
},
true
);
};
// 初始化图表
const initChart = () => {
if (!chartRef.value) return;
if (chartInstance) chartInstance.dispose();
chartInstance = echarts.init(chartRef.value);
// 点击图表打开概况弹框(保留原卡片点击行为)
chartInstance.on('click', handleCardClick);
renderChart();
};
const handleResize = () => {
if (chartInstance) chartInstance.resize();
};
onMounted(() => {
nextTick(() => {
initChart();
setTimeout(() => {
if (chartInstance) chartInstance.resize();
}, 200);
if (!resizeObserver && chartRef.value) {
resizeObserver = new ResizeObserver(() => {
if (chartInstance) chartInstance.resize();
});
resizeObserver.observe(chartRef.value);
}
});
window.addEventListener('resize', handleResize);
});
onBeforeUnmount(() => {
if (chartInstance) {
chartInstance.dispose();
chartInstance = null;
}
window.removeEventListener('resize', handleResize);
if (resizeObserver) {
resizeObserver.disconnect();
resizeObserver = null;
}
});
// ==================== 事件处理 ====================
const handlePanelChange = (data: any) => {
console.log('当前所有控件状态:', data);
if (data.select) {
select.value.value = data.select;
}
if (data.datetime) {
datetimePicker.value.value = data.datetime;
}
};
const handleCardClick = () => {
console.log('卡片被点击,准备打开弹框');
console.log('modalVisible:', datetimePicker.value.value);
modalVisible.value = true;
console.log('modalVisible:', modalVisible.value);
};
const handleModalClose = () => {
modalVisible.value = false;
};
// ==================== 获取默认年份 ====================
const getDefaultYear = async () => {
if (!baseid.value) return;
try {
// const params = {
// filter: { baseId: baseid.value },
// group: [{ dir: 'des', field: 'yr' }]
// };
let params = {
filter: {
logic: 'and',
filters: [
baseid.value != 'all'
? {
field: 'baseId',
operator: 'eq',
dataType: 'string',
value: baseid.value
}
: null
].filter(Boolean)
},
group: [
{
dir: 'des',
field: 'yr'
}
]
};
const res = await getDftYear(params);
const data = res?.data?.data?.[0] || {};
const allYears = Object.values(data);
if (allYears?.length) {
const last = (allYears as any[]).flat().sort().pop();
datetimePicker.value.value = last;
} else {
datetimePicker.value.value = moment().format('YYYY');
}
} catch (error) {
console.error('获取默认年份失败:', error);
datetimePicker.value.value = moment().format('YYYY');
}
};
// ==================== 获取选择器数据 ====================
const getSelectData = async () => {
let params = {
filter: {
logic: 'and',
filters: [
{
field: 'wbsType',
operator: 'eq',
value: 'PSB_RVCD'
},
baseid.value != 'all'
? {
field: 'objId',
operator: 'eq',
value: '水生生态调查情况'
}
: 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;
select.value.options = data.map((item: any) => {
return {
value: item.wbsCode,
label: item.wbsName
};
});
};
// 监听电站变化(优先使用父组件 provide 的电站上下文,兜底 jidiStore
const injectedStation = inject<any>('dianZhanStation', null);
const stationSource = computed(
() => injectedStation?.value || JidiSelectEventStore.selectedItem
);
// ==================== 监听基地变化 ====================
watch(
() => stationSource.value,
async newVal => {
if (newVal && newVal.wbsCode) {
baseid.value = newVal.wbsCode;
getSelectData();
getDefaultYear();
}
},
{ deep: true, immediate: true }
);
</script>
<style lang="scss" scoped>
.chart-container {
width: 100%;
height: 200px;
}
</style>