2026-05-08 14:15:44 +08:00
|
|
|
|
<template>
|
2026-06-05 16:10:14 +08:00
|
|
|
|
<a-modal
|
|
|
|
|
|
:open="visible"
|
2026-06-12 16:59:35 +08:00
|
|
|
|
:title="title + ' ' + '详情信息'"
|
2026-06-05 16:10:14 +08:00
|
|
|
|
width="80vw"
|
|
|
|
|
|
:footer="null"
|
|
|
|
|
|
:closable="true"
|
|
|
|
|
|
@cancel="handleClose"
|
|
|
|
|
|
:destroyOnClose="true"
|
|
|
|
|
|
class="map-modal"
|
|
|
|
|
|
>
|
2026-06-08 09:33:06 +08:00
|
|
|
|
<!-- 问题:
|
|
|
|
|
|
1.基础信息图片展示是什么逻辑
|
|
|
|
|
|
2. 电站专题展示逻辑
|
2026-06-10 15:45:16 +08:00
|
|
|
|
3. 实时视频回放 少接口✅️
|
2026-06-08 09:33:06 +08:00
|
|
|
|
4. 预警提示 少接口
|
2026-06-10 15:45:16 +08:00
|
|
|
|
5. 生态流量 达标率查询不对(✅️)
|
2026-06-08 09:33:06 +08:00
|
|
|
|
6. 鱼类适应性繁殖同期对比NAN (王)
|
2026-06-09 11:44:29 +08:00
|
|
|
|
7. 出库水温 综合分析 导出没做
|
2026-06-10 15:45:16 +08:00
|
|
|
|
8. 栖息地-流量监测 没有水位视频和流量视频 字段没数据
|
|
|
|
|
|
9. 栖息地 水温、水质、流量没有数据没法测
|
2026-06-12 18:42:54 +08:00
|
|
|
|
10.鱼类增殖站 - 运行数据 要添加字典
|
2026-06-10 15:45:16 +08:00
|
|
|
|
|
2026-06-08 09:33:06 +08:00
|
|
|
|
-->
|
2026-06-03 18:25:57 +08:00
|
|
|
|
<div v-if="modelStore.showStcdSelector" class="stcd-selector-wrapper">
|
2026-06-05 16:10:14 +08:00
|
|
|
|
<a-select
|
|
|
|
|
|
v-model:value="modelStore.params.stcd"
|
|
|
|
|
|
placeholder="请选择测站"
|
|
|
|
|
|
style="width: 240px; margin-bottom: 12px"
|
|
|
|
|
|
:options="modelStore.stcdOptions"
|
|
|
|
|
|
show-search
|
|
|
|
|
|
:filter-option="filterOption"
|
|
|
|
|
|
@change="handleStcdChange"
|
|
|
|
|
|
>
|
2026-06-03 18:25:57 +08:00
|
|
|
|
</a-select>
|
|
|
|
|
|
</div>
|
2026-06-12 16:59:35 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 加载状态提示 -->
|
|
|
|
|
|
<div v-if="isLoading" class="loading-container">
|
|
|
|
|
|
<a-spin tip="加载中..." />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Tabs 区域 - 等待加载完成后显示 -->
|
|
|
|
|
|
<a-tabs v-else :active-key="currentActiveKey" @change="onTabChange">
|
2026-05-09 19:30:03 +08:00
|
|
|
|
<a-tab-pane v-for="tab in tabsConfig" :key="tab.key" :tab="tab.name">
|
2026-05-08 19:11:10 +08:00
|
|
|
|
</a-tab-pane>
|
2026-06-10 15:45:16 +08:00
|
|
|
|
<template #rightExtra v-if="anchor.sttp == 'ENG' || anchor.sttp == 'eng'">
|
2026-06-12 16:59:35 +08:00
|
|
|
|
<a-tooltip :title="!hasPowerStatData ? '该电站无专题配置' : ''">
|
|
|
|
|
|
<a-button
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
:disabled="!hasPowerStatData"
|
|
|
|
|
|
@click="gotoEngTopic"
|
|
|
|
|
|
>
|
2026-05-11 17:45:09 +08:00
|
|
|
|
<i class="icon iconfont icon-topic mr-[5px]"></i>
|
|
|
|
|
|
电站专题
|
2026-06-05 16:10:14 +08:00
|
|
|
|
</a-button></a-tooltip
|
|
|
|
|
|
>
|
2026-05-09 19:30:03 +08:00
|
|
|
|
</template>
|
2026-05-08 19:11:10 +08:00
|
|
|
|
</a-tabs>
|
2026-06-12 16:59:35 +08:00
|
|
|
|
|
2026-06-05 16:10:14 +08:00
|
|
|
|
<!-- 内容区域 - 使用动态组件 + keep-alive 实现按需加载和缓存 -->
|
|
|
|
|
|
<keep-alive>
|
2026-06-12 16:59:35 +08:00
|
|
|
|
<div v-if="!isLoading" class="content">
|
2026-06-10 15:45:16 +08:00
|
|
|
|
<div class="content-wrapper" v-show="isQxdMode(currentActiveKey)">
|
|
|
|
|
|
测站:
|
|
|
|
|
|
<a-select
|
|
|
|
|
|
v-model:value="currentQxdSelectedStcd"
|
|
|
|
|
|
:options="qxdStationOptions"
|
|
|
|
|
|
style="width: 200px; margin-bottom: 12px"
|
|
|
|
|
|
placeholder="请选择站点"
|
|
|
|
|
|
@change="handleQxdStationChange"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
2026-06-05 16:10:14 +08:00
|
|
|
|
<!-- 基本信息 -->
|
|
|
|
|
|
<BasicInfo
|
|
|
|
|
|
v-show="currentActiveKey === 'basicInfo'"
|
|
|
|
|
|
:url="getTabUrl('basicInfo')"
|
|
|
|
|
|
:is-active="currentActiveKey === 'basicInfo'"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<!-- 实时视频 -->
|
|
|
|
|
|
<VideoInfo
|
|
|
|
|
|
v-show="currentActiveKey === 'videoInfo'"
|
|
|
|
|
|
:is-active="currentActiveKey === 'videoInfo'"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<!-- 全景影像 -->
|
|
|
|
|
|
<PanoramaInfo
|
|
|
|
|
|
v-show="currentActiveKey === 'panoramaInfo'"
|
|
|
|
|
|
:url="getTabUrl('panoramaInfo')"
|
|
|
|
|
|
:is-active="currentActiveKey === 'panoramaInfo'"
|
|
|
|
|
|
/>
|
2026-06-09 11:44:29 +08:00
|
|
|
|
<!-- 监测数据 - 电站运行过程线 -->
|
2026-06-05 16:10:14 +08:00
|
|
|
|
<MonitorInfo
|
|
|
|
|
|
v-show="currentActiveKey === 'monitorInfo'"
|
|
|
|
|
|
:is-active="currentActiveKey === 'monitorInfo'"
|
2026-06-09 11:44:29 +08:00
|
|
|
|
/>
|
|
|
|
|
|
<!-- 监测数据 - 水温 -->
|
|
|
|
|
|
<WaterTemperature
|
|
|
|
|
|
v-show="currentActiveKey === 'WaterTemperature'"
|
|
|
|
|
|
:is-active="currentActiveKey === 'WaterTemperature'"
|
2026-06-10 15:45:16 +08:00
|
|
|
|
:code="getTabCode('WaterTemperature')"
|
|
|
|
|
|
:stcd="
|
|
|
|
|
|
getTabCode('WaterTemperature') == 'qxd.tabs.jcsj'
|
|
|
|
|
|
? qxdSelectedStcd
|
|
|
|
|
|
: ''
|
|
|
|
|
|
"
|
2026-06-12 16:59:35 +08:00
|
|
|
|
:wt-config="modelStore.wtConfig"
|
2026-06-09 11:44:29 +08:00
|
|
|
|
/>
|
|
|
|
|
|
<!-- 监测数据 - 垂向水温 -->
|
|
|
|
|
|
<VerticalWaterTemperature
|
|
|
|
|
|
v-show="currentActiveKey === 'VerticalWaterTemperature'"
|
|
|
|
|
|
:is-active="currentActiveKey === 'VerticalWaterTemperature'"
|
2026-06-12 16:59:35 +08:00
|
|
|
|
:stcd="modelStore.verticalWaterStcd || modelStore.params.stcd"
|
2026-06-05 16:10:14 +08:00
|
|
|
|
/>
|
2026-06-10 15:45:16 +08:00
|
|
|
|
<!-- 监测数据 - 水质 -->
|
|
|
|
|
|
<WaterQuality
|
|
|
|
|
|
v-show="currentActiveKey === 'WaterQuality'"
|
|
|
|
|
|
:is-active="currentActiveKey === 'WaterQuality'"
|
|
|
|
|
|
:code="getTabCode('WaterQuality')"
|
|
|
|
|
|
:stcd="
|
|
|
|
|
|
getTabCode('WaterQuality') == 'qxd.tabs.szjc'
|
|
|
|
|
|
? qxdSelectedStcdWq
|
|
|
|
|
|
: ''
|
|
|
|
|
|
"
|
2026-06-12 16:59:35 +08:00
|
|
|
|
:wq-show="modelStore.wqShow"
|
2026-06-10 15:45:16 +08:00
|
|
|
|
/>
|
|
|
|
|
|
<!-- 流量监测 -->
|
|
|
|
|
|
<FlowMeasure
|
|
|
|
|
|
v-show="currentActiveKey === 'FlowMeasure'"
|
|
|
|
|
|
:is-active="currentActiveKey === 'FlowMeasure'"
|
|
|
|
|
|
:url="getTabUrl('FlowMeasure')"
|
|
|
|
|
|
:code="getTabCode('FlowMeasure')"
|
|
|
|
|
|
:stcd="
|
|
|
|
|
|
getTabCode('FlowMeasure') == 'qxd.tabs.lcjs'
|
|
|
|
|
|
? qxdSelectedStcdZq
|
|
|
|
|
|
: ''
|
|
|
|
|
|
"
|
|
|
|
|
|
/>
|
2026-06-11 09:36:40 +08:00
|
|
|
|
<!-- 在线监测数据 -->
|
|
|
|
|
|
<FishFacilityMonitorData
|
|
|
|
|
|
v-show="currentActiveKey === 'FishFacilityMonitorData'"
|
|
|
|
|
|
:is-active="currentActiveKey === 'FishFacilityMonitorData'"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<!-- 运行情况 -->
|
|
|
|
|
|
<FishFacilityRunState
|
|
|
|
|
|
v-show="currentActiveKey === 'FishFacilityRunState'"
|
|
|
|
|
|
:is-active="currentActiveKey === 'FishFacilityRunState'"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<!-- 综合分析 -->
|
|
|
|
|
|
<FishZHFX
|
|
|
|
|
|
v-show="currentActiveKey === 'FishZHFX'"
|
|
|
|
|
|
:is-active="currentActiveKey === 'FishZHFX'"
|
|
|
|
|
|
/>
|
2026-06-12 18:42:54 +08:00
|
|
|
|
<!-- AI运行识别 -->
|
|
|
|
|
|
<AIYXSB
|
|
|
|
|
|
v-show="currentActiveKey === 'AIYXSB'"
|
|
|
|
|
|
:is-active="currentActiveKey === 'AIYXSB'"
|
|
|
|
|
|
/>
|
2026-06-05 16:10:14 +08:00
|
|
|
|
<!-- 预警提示 -->
|
|
|
|
|
|
<EarlyWarningAlert
|
|
|
|
|
|
v-show="currentActiveKey === 'tableTabs'"
|
|
|
|
|
|
:tabs-items="getTabChildren('tableTabs')"
|
|
|
|
|
|
:is-active="currentActiveKey === 'tableTabs'"
|
|
|
|
|
|
/>
|
2026-06-08 09:33:06 +08:00
|
|
|
|
<!-- 生态流量 -->
|
|
|
|
|
|
<EcologicalFlow
|
|
|
|
|
|
v-show="currentActiveKey === 'EcologicalFlow'"
|
|
|
|
|
|
:is-active="currentActiveKey === 'EcologicalFlow'"
|
|
|
|
|
|
/>
|
2026-06-05 16:10:14 +08:00
|
|
|
|
<!-- 鱼类繁殖适宜性分析 -->
|
|
|
|
|
|
<WaterTemperatureRep
|
|
|
|
|
|
v-show="currentActiveKey === 'WaterTemperatureRep'"
|
|
|
|
|
|
:is-active="currentActiveKey === 'WaterTemperatureRep'"
|
|
|
|
|
|
/>
|
2026-06-12 18:42:54 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 鱼类增殖站 - 运行数据 -->
|
|
|
|
|
|
<NormalOperationData
|
|
|
|
|
|
v-show="currentActiveKey === 'NormalOperationData'"
|
|
|
|
|
|
:is-active="currentActiveKey === 'NormalOperationData'"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<!-- 增值放流情况 -->
|
|
|
|
|
|
<NormalAddedSituation
|
|
|
|
|
|
v-show="currentActiveKey === 'NormalAddedSituation'"
|
|
|
|
|
|
:is-active="currentActiveKey === 'NormalAddedSituation'"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<!-- 科研情况 -->
|
|
|
|
|
|
<NormalResearchSituation
|
|
|
|
|
|
v-show="currentActiveKey === 'NormalResearchSituation'"
|
|
|
|
|
|
:is-active="currentActiveKey === 'NormalResearchSituation'"
|
|
|
|
|
|
/>
|
2026-06-05 16:10:14 +08:00
|
|
|
|
<!-- 查看报告 -->
|
|
|
|
|
|
<Attachment
|
|
|
|
|
|
v-show="currentActiveKey === 'attachment'"
|
|
|
|
|
|
:is-active="currentActiveKey === 'attachment'"
|
|
|
|
|
|
tabKey="attachment"
|
|
|
|
|
|
:show-download="false"
|
|
|
|
|
|
:url="getTabUrl('attachment')"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<!-- 批复文件 -->
|
|
|
|
|
|
<Attachment
|
|
|
|
|
|
v-show="currentActiveKey === 'approval'"
|
|
|
|
|
|
:is-active="currentActiveKey === 'approval'"
|
|
|
|
|
|
tabKey="approval"
|
|
|
|
|
|
:show-download="true"
|
|
|
|
|
|
:url="getTabUrl('approval')"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</keep-alive>
|
2026-05-08 14:15:44 +08:00
|
|
|
|
</a-modal>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
2026-06-05 16:10:14 +08:00
|
|
|
|
import { ref, watch, reactive, computed } from 'vue';
|
2026-05-08 14:15:44 +08:00
|
|
|
|
// 导入预定义的 Tab 内容组件
|
2026-06-05 16:10:14 +08:00
|
|
|
|
import BasicInfo from './components/BasicInfo.vue'; // 基本信息
|
|
|
|
|
|
import VideoInfo from './components/videoInfo.vue'; // 实时视频
|
|
|
|
|
|
import PanoramaInfo from './components/PanoramaInfo.vue'; // 全景影像
|
2026-06-09 11:44:29 +08:00
|
|
|
|
import MonitorInfo from './components/MonitorInfo.vue'; // 电站运行过程线
|
|
|
|
|
|
import WaterTemperature from './components/WaterTemperature.vue'; // 水温
|
|
|
|
|
|
import VerticalWaterTemperature from './components/VerticalWaterTemperature.vue'; // 垂向水温
|
2026-06-10 15:45:16 +08:00
|
|
|
|
import WaterQuality from './components/WaterQuality.vue'; // 水质
|
2026-06-12 18:42:54 +08:00
|
|
|
|
import AIYXSB from './components/AIYXSB/index.vue'; // AI运行识别
|
2026-06-05 16:10:14 +08:00
|
|
|
|
import EarlyWarningAlert from './components/EarlyWarningAlert.vue'; // 预警提示
|
2026-06-10 15:45:16 +08:00
|
|
|
|
import FlowMeasure from './components/FlowMeasure.vue'; // 流量监测
|
2026-06-11 09:36:40 +08:00
|
|
|
|
import FishFacilityMonitorData from './components/FishFacilityMonitorData.vue'; // 在线监测数据
|
|
|
|
|
|
import FishFacilityRunState from './components/FishFacilityRunState.vue'; // 运行情况
|
2026-06-12 18:42:54 +08:00
|
|
|
|
// 鱼类增殖站
|
|
|
|
|
|
import NormalOperationData from './components/NormalOperationData/index.vue'; // 运行数据
|
|
|
|
|
|
import NormalAddedSituation from './components/NormalAddedSituation.vue'; // 增值放流情况
|
|
|
|
|
|
import NormalResearchSituation from './components/NormalResearchSituation.vue'; // 科研情况
|
|
|
|
|
|
|
2026-06-11 09:36:40 +08:00
|
|
|
|
import FishZHFX from './components/FishZHFX.vue'; // 鱼类繁殖适宜性分析
|
2026-06-08 09:33:06 +08:00
|
|
|
|
import EcologicalFlow from './components/EcologicalFlow.vue'; // 生态流量
|
2026-06-05 16:10:14 +08:00
|
|
|
|
import Attachment from './components/Attachment.vue'; // 查看报告/批复文件
|
|
|
|
|
|
import WaterTemperatureRep from './components/WaterTemperatureRep.vue'; // 水温对比数据
|
|
|
|
|
|
import { useModelStore } from '@/store/modules/model';
|
|
|
|
|
|
import { handleTabs } from './setting.config';
|
2026-06-10 15:45:16 +08:00
|
|
|
|
import {
|
|
|
|
|
|
getMonitorDataWt,
|
|
|
|
|
|
getMonitorDataWq,
|
2026-06-12 16:59:35 +08:00
|
|
|
|
getMonitorDataZq,
|
|
|
|
|
|
getBuildState,
|
|
|
|
|
|
getFishTab,
|
|
|
|
|
|
checkAnalysisShow,
|
|
|
|
|
|
getStInfoByStcd,
|
|
|
|
|
|
getVideoList,
|
|
|
|
|
|
getMonitorDataWaterTempPowerStation,
|
|
|
|
|
|
getMonitorDataWaterTempPowerStation2,
|
|
|
|
|
|
checkPowerStationTopic
|
2026-06-10 15:45:16 +08:00
|
|
|
|
} from '@/api/mapModal';
|
2026-06-12 16:59:35 +08:00
|
|
|
|
// import { useRouter } from 'vue-router';
|
2026-05-09 19:30:03 +08:00
|
|
|
|
|
|
|
|
|
|
const modelStore = useModelStore();
|
|
|
|
|
|
const tabsConfig = ref([]);
|
2026-06-12 16:59:35 +08:00
|
|
|
|
// 加载状态:等待所有验证完成后再显示 tabs
|
|
|
|
|
|
const isLoading = ref(true);
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== 电站专题相关 ====================
|
|
|
|
|
|
// 电站专题配置数据状态
|
|
|
|
|
|
const hasPowerStatData = ref(false);
|
|
|
|
|
|
// 电站专题 URL 参数(仅 hbb)
|
|
|
|
|
|
const hbbSearchParams = '?menu=dianZhanZhuanTi&page=dianZhanZhuanTi';
|
|
|
|
|
|
// 判断当前是否在电站专题页面
|
|
|
|
|
|
const isPowerStatPage = computed(() => {
|
|
|
|
|
|
return window.location.search === hbbSearchParams;
|
|
|
|
|
|
});
|
|
|
|
|
|
// 判断是否为局级页面(根据当前路由判断)
|
|
|
|
|
|
const isJiangJu = computed(() => {
|
|
|
|
|
|
// TODO: 根据实际路由判断逻辑修改
|
|
|
|
|
|
return false;
|
|
|
|
|
|
});
|
|
|
|
|
|
// const router = useRouter();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 查询电站是否有专题配置数据
|
|
|
|
|
|
*/
|
|
|
|
|
|
const checkPowerStationTopicData = async (stcd: string) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const res = await checkPowerStationTopic({
|
|
|
|
|
|
filter: {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: [
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'stcd',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: stcd
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'bclData',
|
|
|
|
|
|
operator: 'contains',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: 'image/png'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
hasPowerStatData.value =
|
|
|
|
|
|
res?.data?.data && res?.data?.data?.length > 0;
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('查询电站专题配置失败:', error);
|
|
|
|
|
|
hasPowerStatData.value = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 跳转到电站专题页面
|
|
|
|
|
|
*/
|
|
|
|
|
|
const gotoEngTopic = () => {
|
|
|
|
|
|
// TODO: 等待电站专题页面创建后,取消注释以下代码
|
|
|
|
|
|
/*
|
|
|
|
|
|
const url = `/qgc-biz-home/${hbbSearchParams}`;
|
|
|
|
|
|
const menu = {
|
|
|
|
|
|
id: 'dianZhanZhuanTi',
|
|
|
|
|
|
url,
|
|
|
|
|
|
name: '电站专题'
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 缓存当前电站 stcd(跳转后页面会读取)
|
|
|
|
|
|
localStorage.setItem('modalSelectedEngTopic', JSON.stringify({ stcd: modelStore.params.stcd }));
|
|
|
|
|
|
|
|
|
|
|
|
// 关闭弹窗
|
|
|
|
|
|
handleClose();
|
|
|
|
|
|
|
|
|
|
|
|
// 使用 Vue Router 跳转
|
|
|
|
|
|
// router.push(url);
|
|
|
|
|
|
*/
|
|
|
|
|
|
console.log('电站专题跳转(暂未实现):', modelStore.params.stcd);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 环境判断变量(与 React 版本对齐)
|
|
|
|
|
|
const app = 'hbb'; // 模拟 React 中的 Session.getAppCode()
|
|
|
|
|
|
const env = 'hbb'; // 模拟 React 中的 window.__env__
|
|
|
|
|
|
const isLCJ = env?.startsWith('lcj');
|
|
|
|
|
|
const sttpList = ['ENG', 'WT', 'WQ', 'FP', 'FB', 'VP', 'DW', 'EQ', 'VA'];
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== 异步 Tab 过滤逻辑 ====================
|
|
|
|
|
|
|
|
|
|
|
|
// 功能6: 垂向水温与 AI 识别动态过滤
|
|
|
|
|
|
const checkVerticalWaterAndAI = async (stcd: string) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const res = await getStInfoByStcd({ stcd });
|
|
|
|
|
|
const data = res?.data || res;
|
|
|
|
|
|
if (data && data.relList) {
|
|
|
|
|
|
const jianCei = data.relList.find(
|
|
|
|
|
|
(item: any) => item.sttpCode === 'WTVT'
|
|
|
|
|
|
);
|
|
|
|
|
|
const aiShiBie = data.relList.filter((item: any) =>
|
|
|
|
|
|
item?.sttpCode?.startsWith('AI')
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (!jianCei) {
|
|
|
|
|
|
// 无垂向水温子站点,过滤掉垂向水温 Tab
|
|
|
|
|
|
tabsConfig.value = tabsConfig.value.filter(
|
|
|
|
|
|
(item: any) => item.type !== 'VerticalWaterTemperature'
|
|
|
|
|
|
);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
modelStore.verticalWaterStcd = jianCei.stcd;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!aiShiBie.length) {
|
|
|
|
|
|
// 无 AI 识别子站点,过滤掉 AI 识别 Tab
|
|
|
|
|
|
tabsConfig.value = tabsConfig.value.filter(
|
|
|
|
|
|
(item: any) => item.type !== 'AIYXSB'
|
|
|
|
|
|
);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
modelStore.aiSites = aiShiBie;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('垂向水温/AI 检查失败:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 功能7: 视频存在性检查
|
|
|
|
|
|
const checkVideoExists = async (stcd: string) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const res = await getVideoList({
|
|
|
|
|
|
filter: {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: [{ field: 'stcd', operator: 'eq', value: stcd }]
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
if (!res?.data?.data?.length && !res?.data?.records?.length) {
|
|
|
|
|
|
// 无视频数据,过滤掉视频 Tab
|
|
|
|
|
|
tabsConfig.value = tabsConfig.value.filter(
|
|
|
|
|
|
(item: any) => item.type !== 'video'
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('视频检查失败:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 功能8: 鱼类栖息地数据类型检查 (React: isLCJ && sttpCode === 'WE')
|
|
|
|
|
|
const checkFishTab = async (stcd: string) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const res = await getFishTab(stcd);
|
|
|
|
|
|
const data = res?.data || res;
|
|
|
|
|
|
if (data && data.length > 0) {
|
|
|
|
|
|
modelStore.fishTabInfo = data[0];
|
|
|
|
|
|
// 根据 hasWt/hasWq/hasFv 过滤 FlowMeasure 的子 Tab
|
|
|
|
|
|
const flowTab = tabsConfig.value.find(
|
|
|
|
|
|
(item: any) => item.key === 'FlowMeasure'
|
|
|
|
|
|
);
|
|
|
|
|
|
if (flowTab && flowTab.tabs) {
|
|
|
|
|
|
flowTab.tabs = flowTab.tabs.filter((tab: any) => {
|
|
|
|
|
|
if (tab.name === '水温(℃)' && !data[0].hasWt) return false;
|
|
|
|
|
|
if (tab.name === '水质' && !data[0].hasWq) return false;
|
|
|
|
|
|
if (tab.name === '流速(m/s)' && !data[0].hasFv) return false;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('鱼类数据检查失败:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 功能9: 水质 AI 预测功能检查 (React: (app === "hbb" || baseId === "07" || "02") && sttpCode === 'WQ'/'WQFB'/'wq')
|
|
|
|
|
|
const checkAnalysisAvailability = async (stcd: string) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const filter = {
|
|
|
|
|
|
filter: {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: [
|
|
|
|
|
|
{ field: 'stcd', operator: 'eq', value: stcd },
|
|
|
|
|
|
{ field: 'mway', operator: 'eq', value: '2' },
|
|
|
|
|
|
{ field: 'dtinType', operator: 'eq', value: '0' },
|
|
|
|
|
|
{
|
|
|
|
|
|
logic: 'or',
|
|
|
|
|
|
filters: [
|
|
|
|
|
|
{ field: 'engLctn3Code', operator: 'isnotnull' },
|
|
|
|
|
|
{ field: 'engLctn1Code', operator: 'isnotnull' }
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
const res = await checkAnalysisShow(filter);
|
|
|
|
|
|
modelStore.wqShow = !!res?.data;
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('水质 AI 预测检查失败:', error);
|
|
|
|
|
|
modelStore.wqShow = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 功能10: 水温站特殊处理 (React: (app === "hbb" || baseId === "07" || "02") && sttpCode === 'WT'/'wt')
|
|
|
|
|
|
const checkWaterTempConfig = async (stcd: string) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const [configRes, dwRes, buildRes] = await Promise.all([
|
|
|
|
|
|
getMonitorDataWaterTempPowerStation({ stcd }),
|
|
|
|
|
|
getMonitorDataWaterTempPowerStation2({ stcd }),
|
|
|
|
|
|
getBuildState({
|
|
|
|
|
|
filter: {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: [{ field: 'stcd', operator: 'eq', value: stcd }]
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
modelStore.wtConfig = {
|
|
|
|
|
|
ioWtrv: configRes?.data?.ioWtrv,
|
|
|
|
|
|
hasRstcdWtvt: dwRes?.data
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 检查出入库水温对比
|
|
|
|
|
|
const buildData = buildRes?.data?.[0];
|
|
|
|
|
|
if (!buildData?.engIwtCode && !buildData?.engDwtCode) {
|
|
|
|
|
|
tabsConfig.value = tabsConfig.value.filter(
|
|
|
|
|
|
(item: any) => item.name !== '出入库水温对比'
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('水温配置检查失败:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 功能11: 电站建设状态过滤 (React: sttp == "ENG" && eqtp != "QEC")
|
|
|
|
|
|
const checkBuildState = async (stcd: string) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const res = await getBuildState({
|
|
|
|
|
|
filter: {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: [{ field: 'stcd', operator: 'eq', value: stcd }]
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const buid = res?.data?.[0]?.bldsttCcode;
|
|
|
|
|
|
// 0 未建 1 在建 2 已建
|
|
|
|
|
|
const zj = ['基础信息', '实时视频', '全景影像', '查看报告'];
|
|
|
|
|
|
const wj = ['基础信息', '查看报告'];
|
|
|
|
|
|
|
|
|
|
|
|
if (res?.data?.length > 0) {
|
|
|
|
|
|
const zJTabData = tabsConfig.value?.filter((item: any) =>
|
|
|
|
|
|
zj.includes(item.name)
|
|
|
|
|
|
);
|
|
|
|
|
|
const wJTabData = tabsConfig.value?.filter((item: any) =>
|
|
|
|
|
|
wj.includes(item.name)
|
|
|
|
|
|
);
|
|
|
|
|
|
tabsConfig.value =
|
|
|
|
|
|
buid == 1 ? zJTabData : buid == 0 ? wJTabData : tabsConfig.value;
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('建设状态检查失败:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// QGC 完整 Tab 过滤逻辑(与 React setQGCTabList 对齐)
|
|
|
|
|
|
const setQGCTabList = async (_tabs: any, stcd: string) => {
|
|
|
|
|
|
let tabs = [..._tabs];
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 1. 电站建设状态过滤
|
|
|
|
|
|
if (modelStore.params.sttp == 'ENG' && modelStore.params.eqtp != 'QEC') {
|
|
|
|
|
|
const res = await getBuildState({
|
|
|
|
|
|
filter: {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: [{ field: 'stcd', operator: 'eq', value: stcd }]
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const buid = res?.data?.[0]?.bldsttCcode;
|
|
|
|
|
|
const zj = ['基础信息', '实时视频', '全景影像', '查看报告'];
|
|
|
|
|
|
const wj = ['基础信息', '查看报告'];
|
|
|
|
|
|
|
|
|
|
|
|
if (res?.data?.length > 0) {
|
|
|
|
|
|
const zJTabData = tabs?.filter((item: any) => zj.includes(item.name));
|
|
|
|
|
|
const wJTabData = tabs?.filter((item: any) => wj.includes(item.name));
|
|
|
|
|
|
tabs = buid == 1 ? zJTabData : buid == 0 ? wJTabData : tabs;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 垂向水温 & AI 识别检查(对所有类型执行,与 React 一致)
|
|
|
|
|
|
const res4 = await getStInfoByStcd({ stcd });
|
|
|
|
|
|
let newTabs = [...tabs];
|
|
|
|
|
|
|
|
|
|
|
|
if (res4 && res4.data && res4.data.relList) {
|
|
|
|
|
|
const relList = res4.data.relList;
|
|
|
|
|
|
const jianCei = relList.find((item: any) => item.sttpCode === 'WTVT');
|
|
|
|
|
|
const aiShiBie = relList.filter((item: any) =>
|
|
|
|
|
|
item?.sttpCode?.startsWith('AI')
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (!jianCei) {
|
|
|
|
|
|
// newTabs = newTabs.filter(
|
|
|
|
|
|
// item => item.type !== 'VerticalWaterTemperature'
|
|
|
|
|
|
// );
|
|
|
|
|
|
} else {
|
|
|
|
|
|
modelStore.verticalWaterStcd = jianCei.stcd;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!aiShiBie.length) {
|
|
|
|
|
|
newTabs = newTabs.filter(item => item.type !== 'AIYXSB');
|
|
|
|
|
|
} else {
|
|
|
|
|
|
modelStore.aiSites = aiShiBie;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 视频存在性检查
|
|
|
|
|
|
let params = {
|
|
|
|
|
|
filter: {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: [
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'sttpCode',
|
|
|
|
|
|
operator: 'startswith',
|
|
|
|
|
|
value: 'VD_'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
logic: 'or',
|
|
|
|
|
|
filters: [
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'rstcd',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: stcd
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'stcd',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: stcd
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'fhstcd',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: stcd
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'stCode',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: stcd
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
select: ['stcd', 'stnm', 'sttpCode', 'sttpName', 'playWay', 'url'],
|
|
|
|
|
|
sort: [
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'stnm',
|
|
|
|
|
|
dir: 'asc'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
};
|
|
|
|
|
|
const res2 = await getVideoList(params);
|
|
|
|
|
|
console.log('', modelStore.params.sttp);
|
|
|
|
|
|
debugger
|
|
|
|
|
|
if (
|
|
|
|
|
|
(res2?.data?.data?.length > 0 || res2?.data?.records?.length > 0) ||
|
|
|
|
|
|
modelStore.params.sttp == 'WQ'
|
|
|
|
|
|
) {
|
|
|
|
|
|
tabsConfig.value = newTabs;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
tabsConfig.value = newTabs.filter((item: any) => item.type != 'video');
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('QGC Tab 过滤失败:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 综合过滤函数(与 React useEffect 逻辑对齐)
|
|
|
|
|
|
const applyTabFilters = async (params: any) => {
|
|
|
|
|
|
isLoading.value = true; // 开始加载
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const sttpCode = params?.sttp;
|
|
|
|
|
|
const stcd = params?.stcd;
|
|
|
|
|
|
const eqtp = params?.eqtp;
|
|
|
|
|
|
const baseId = modelStore.baseId;
|
|
|
|
|
|
|
|
|
|
|
|
if (!stcd) return;
|
|
|
|
|
|
|
|
|
|
|
|
// 按照 React 的分支逻辑执行(注意运算符优先级)
|
|
|
|
|
|
if (isLCJ && sttpCode === 'VP') {
|
|
|
|
|
|
// LCJ 珍稀植物园视频检查
|
|
|
|
|
|
const res = await getVideoList({
|
|
|
|
|
|
filter: {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: [{ field: 'stcd', operator: 'eq', value: stcd }]
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
if (!res?.data?.data?.length && !res?.data?.records?.length) {
|
|
|
|
|
|
tabsConfig.value = tabsConfig.value.filter(
|
|
|
|
|
|
item => item.name != '实时视频'
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (isLCJ && sttpCode === 'WE') {
|
|
|
|
|
|
// LCJ 鱼类栖息地数据类型检查
|
|
|
|
|
|
await checkFishTab(stcd);
|
|
|
|
|
|
} else if (
|
|
|
|
|
|
((baseId === '07' || baseId === '02') && sttpCode === 'WQ') ||
|
|
|
|
|
|
sttpCode === 'WQFB' ||
|
|
|
|
|
|
sttpCode === 'wq'
|
|
|
|
|
|
) {
|
|
|
|
|
|
// 水质 AI 预测检查(React 逻辑:WQ 需要条件,WQFB/wq 无条件)
|
|
|
|
|
|
await checkAnalysisAvailability(stcd);
|
|
|
|
|
|
} else if (
|
|
|
|
|
|
((baseId === '07' || baseId === '02') && sttpCode === 'WT') ||
|
|
|
|
|
|
sttpCode === 'wt'
|
|
|
|
|
|
) {
|
|
|
|
|
|
// 水温站特殊处理(React 逻辑:WT 需要条件,wt 无条件)
|
|
|
|
|
|
await checkWaterTempConfig(stcd);
|
|
|
|
|
|
} else if (
|
|
|
|
|
|
sttpList.includes(sttpCode?.toUpperCase()) ||
|
|
|
|
|
|
sttpCode?.startsWith('FP_') ||
|
|
|
|
|
|
sttpCode?.includes('DW')
|
|
|
|
|
|
) {
|
|
|
|
|
|
// QGC 完整 Tab 过滤(包含建设状态、垂向水温、AI识别、视频检查)
|
|
|
|
|
|
await setQGCTabList(tabsConfig.value, stcd);
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('Tab 过滤逻辑执行失败:', error);
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
isLoading.value = false; // 无论成功失败都停止加载
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2026-06-10 15:45:16 +08:00
|
|
|
|
|
|
|
|
|
|
// ==================== qxd 栖息地模式相关 ====================
|
|
|
|
|
|
// qxd模式配置映射
|
|
|
|
|
|
const qxdConfigMap: Record<
|
|
|
|
|
|
string,
|
|
|
|
|
|
{
|
|
|
|
|
|
sttpCode: string;
|
|
|
|
|
|
apiFn: (data: any) => Promise<any>;
|
|
|
|
|
|
selectProp: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
> = {
|
|
|
|
|
|
'qxd.tabs.jcsj': {
|
|
|
|
|
|
// 水温
|
|
|
|
|
|
sttpCode: 'WTRV',
|
|
|
|
|
|
apiFn: getMonitorDataWt,
|
|
|
|
|
|
selectProp: 'qxdSelectedStcd'
|
|
|
|
|
|
},
|
|
|
|
|
|
'qxd.tabs.szjc': {
|
|
|
|
|
|
// 水质
|
|
|
|
|
|
sttpCode: 'WQ',
|
|
|
|
|
|
apiFn: getMonitorDataWq,
|
|
|
|
|
|
selectProp: 'qxdSelectedStcdWq'
|
|
|
|
|
|
},
|
|
|
|
|
|
'qxd.tabs.lcjs': {
|
|
|
|
|
|
// 流量监测
|
|
|
|
|
|
sttpCode: 'ZQ',
|
|
|
|
|
|
apiFn: getMonitorDataZq,
|
|
|
|
|
|
selectProp: 'qxdSelectedStcdZq'
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 各模式的站点选项和选中值
|
|
|
|
|
|
const qxdStationOptions = ref<{ label: string; value: string }[]>([]);
|
|
|
|
|
|
const qxdSelectedStcd = ref<string>('');
|
|
|
|
|
|
const qxdSelectedStcdWq = ref<string>('');
|
|
|
|
|
|
const qxdSelectedStcdZq = ref<string>('');
|
|
|
|
|
|
const qxdLoadedCodes = ref<Set<string>>(new Set());
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前tab对应的qxd配置
|
|
|
|
|
|
const getCurrentQxdConfig = (tabKey: string) => {
|
|
|
|
|
|
const code = getTabCode(tabKey);
|
|
|
|
|
|
return code && qxdConfigMap[code] ? qxdConfigMap[code] : null;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 获取选中的stcd
|
|
|
|
|
|
const getQxdSelectedStcd = (tabKey: string) => {
|
|
|
|
|
|
const config = getCurrentQxdConfig(tabKey);
|
|
|
|
|
|
if (!config) return '';
|
|
|
|
|
|
switch (config.selectProp) {
|
|
|
|
|
|
case 'qxdSelectedStcd':
|
|
|
|
|
|
return qxdSelectedStcd.value;
|
|
|
|
|
|
case 'qxdSelectedStcdWq':
|
|
|
|
|
|
return qxdSelectedStcdWq.value;
|
|
|
|
|
|
case 'qxdSelectedStcdZq':
|
|
|
|
|
|
return qxdSelectedStcdZq.value;
|
|
|
|
|
|
default:
|
|
|
|
|
|
return '';
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 设置选中的stcd
|
|
|
|
|
|
const setQxdSelectedStcd = (tabKey: string, value: string) => {
|
|
|
|
|
|
const config = getCurrentQxdConfig(tabKey);
|
|
|
|
|
|
if (!config) return;
|
|
|
|
|
|
switch (config.selectProp) {
|
|
|
|
|
|
case 'qxdSelectedStcd':
|
|
|
|
|
|
qxdSelectedStcd.value = value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'qxdSelectedStcdWq':
|
|
|
|
|
|
qxdSelectedStcdWq.value = value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 'qxdSelectedStcdZq':
|
|
|
|
|
|
qxdSelectedStcdZq.value = value;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 加载栖息地站点列表
|
|
|
|
|
|
const loadQxdStationList = async (tabKey: string) => {
|
|
|
|
|
|
const code = getTabCode(tabKey);
|
|
|
|
|
|
if (!code || !qxdConfigMap[code]) return;
|
|
|
|
|
|
if (qxdLoadedCodes.value.has(code)) return;
|
|
|
|
|
|
|
|
|
|
|
|
const config = qxdConfigMap[code];
|
|
|
|
|
|
try {
|
|
|
|
|
|
const params = {
|
|
|
|
|
|
filter: {
|
|
|
|
|
|
logic: 'and',
|
|
|
|
|
|
filters: [
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'fhstcd',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: modelStore.params.stcd
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
field: 'sttpCode',
|
|
|
|
|
|
operator: 'eq',
|
|
|
|
|
|
dataType: 'string',
|
|
|
|
|
|
value: config.sttpCode
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
select: ['stcd', 'stnm']
|
|
|
|
|
|
};
|
|
|
|
|
|
const res = await config.apiFn(params);
|
|
|
|
|
|
const stations = res?.data?.data || res?.data?.records || [];
|
|
|
|
|
|
if (stations.length > 0) {
|
|
|
|
|
|
qxdStationOptions.value = stations.map((item: any) => ({
|
|
|
|
|
|
label: item.stnm,
|
|
|
|
|
|
value: item.stcd
|
|
|
|
|
|
}));
|
|
|
|
|
|
setQxdSelectedStcd(tabKey, stations[0].stcd);
|
|
|
|
|
|
}
|
|
|
|
|
|
qxdLoadedCodes.value.add(code);
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error(`获取站点列表失败(${code}):`, error);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前激活tab对应的选中stcd (支持v-model双向绑定)
|
|
|
|
|
|
const currentQxdSelectedStcd = computed({
|
|
|
|
|
|
get: () => getQxdSelectedStcd(currentActiveKey.value),
|
|
|
|
|
|
set: (val: string) => setQxdSelectedStcd(currentActiveKey.value, val)
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 判断是否是qxd模式
|
|
|
|
|
|
const isQxdMode = (tabKey: string) => {
|
|
|
|
|
|
const code = getTabCode(tabKey);
|
|
|
|
|
|
return code && qxdConfigMap[code] ? true : false;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理栖息地站点切换
|
|
|
|
|
|
const handleQxdStationChange = () => {
|
|
|
|
|
|
// 站点切换后,子组件会通过 watch stcd 自动刷新
|
|
|
|
|
|
};
|
2026-05-08 19:11:10 +08:00
|
|
|
|
// import MapView from './components/MapView.vue';
|
|
|
|
|
|
// import SurroundingInfo from './components/SurroundingInfo.vue';
|
2026-05-08 14:15:44 +08:00
|
|
|
|
|
|
|
|
|
|
// 定义 Tab 配置项接口
|
|
|
|
|
|
interface TabItem {
|
|
|
|
|
|
key: string;
|
|
|
|
|
|
title: string;
|
2026-05-08 19:11:10 +08:00
|
|
|
|
url: string;
|
2026-05-08 14:15:44 +08:00
|
|
|
|
}
|
2026-06-05 16:10:14 +08:00
|
|
|
|
// 获取 Tab 配置项的 URL
|
|
|
|
|
|
const getTabUrl = (key: string) => {
|
|
|
|
|
|
const tab = tabsConfig.value.find((item: any) => item.key === key);
|
|
|
|
|
|
return tab?.url || '';
|
|
|
|
|
|
};
|
|
|
|
|
|
// 获取 Tab 配置项的子 Tab
|
|
|
|
|
|
const getTabChildren = (key: string) => {
|
|
|
|
|
|
console.log(tabsConfig.value);
|
|
|
|
|
|
const tab = tabsConfig.value.find((item: any) => item.key === key);
|
|
|
|
|
|
return tab?.tabs || [];
|
|
|
|
|
|
};
|
|
|
|
|
|
// 获取 Tab 配置项的 code
|
|
|
|
|
|
const getTabCode = (key: string) => {
|
|
|
|
|
|
const tab = tabsConfig.value.find((item: any) => item.key === key);
|
|
|
|
|
|
return tab?.code || '';
|
|
|
|
|
|
};
|
2026-05-08 14:15:44 +08:00
|
|
|
|
// 定义 Props
|
|
|
|
|
|
const props = defineProps<{
|
|
|
|
|
|
visible: boolean;
|
|
|
|
|
|
title?: string;
|
|
|
|
|
|
activeKey?: string; // 外部控制的当前激活 tab
|
|
|
|
|
|
data?: any; // 可选:传递给内部组件的数据
|
|
|
|
|
|
}>();
|
|
|
|
|
|
|
|
|
|
|
|
// 定义 Emits
|
2026-05-08 19:11:10 +08:00
|
|
|
|
// 添加 'update:activeKey' 以支持 v-model:active-key
|
2026-05-08 14:15:44 +08:00
|
|
|
|
const emit = defineEmits<{
|
2026-06-05 16:10:14 +08:00
|
|
|
|
(e: 'update:visible', value: boolean): void;
|
|
|
|
|
|
(e: 'change', key: string): void;
|
2026-05-08 14:15:44 +08:00
|
|
|
|
}>();
|
|
|
|
|
|
|
|
|
|
|
|
// 内部维护的 activeKey
|
2026-06-05 16:10:14 +08:00
|
|
|
|
const currentActiveKey = ref<string>('');
|
2026-06-12 16:59:35 +08:00
|
|
|
|
const anchor = ref<any>('');
|
2026-05-08 14:15:44 +08:00
|
|
|
|
|
2026-05-08 19:11:10 +08:00
|
|
|
|
// 监听外部传入的 activeKey 变化,同步到内部状态
|
|
|
|
|
|
watch(
|
|
|
|
|
|
() => props.activeKey,
|
2026-06-05 16:10:14 +08:00
|
|
|
|
newVal => {
|
2026-05-08 19:11:10 +08:00
|
|
|
|
if (newVal && newVal !== currentActiveKey.value) {
|
|
|
|
|
|
currentActiveKey.value = newVal;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
{ immediate: true }
|
|
|
|
|
|
);
|
2026-05-09 19:30:03 +08:00
|
|
|
|
watch(
|
|
|
|
|
|
() => modelStore.params,
|
2026-06-12 16:59:35 +08:00
|
|
|
|
async newVal => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
if (!newVal || Object.keys(newVal).length === 0) return;
|
2026-05-13 08:45:15 +08:00
|
|
|
|
console.log(newVal);
|
2026-06-10 15:45:16 +08:00
|
|
|
|
anchor.value = newVal;
|
|
|
|
|
|
let params = newVal;
|
|
|
|
|
|
if (['VD', 'WTRV', 'ZQ', 'WQ'].includes(params?.sttpCode)) {
|
|
|
|
|
|
params.sttp = params.sttpCode;
|
2026-06-12 18:42:54 +08:00
|
|
|
|
} else if (['ENG_ALARM'].includes(params?.sttpMap)) {
|
2026-06-10 18:54:40 +08:00
|
|
|
|
params.sttp = params.sttpMap;
|
2026-06-10 15:45:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
tabsConfig.value = handleTabs({ ...params });
|
2026-05-11 17:45:09 +08:00
|
|
|
|
let value = tabsConfig.value.find((item: any) => item.default);
|
|
|
|
|
|
currentActiveKey.value = value?.key;
|
2026-06-12 16:59:35 +08:00
|
|
|
|
|
|
|
|
|
|
// 电站类型时,查询电站专题配置数据
|
|
|
|
|
|
if (params?.sttp?.toUpperCase() === 'ENG') {
|
|
|
|
|
|
checkPowerStationTopicData(params.stcd);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 应用异步 Tab 过滤(非阻塞式)
|
|
|
|
|
|
applyTabFilters(params);
|
2026-05-09 19:30:03 +08:00
|
|
|
|
},
|
|
|
|
|
|
{ deep: true, immediate: true }
|
|
|
|
|
|
);
|
2026-06-10 15:45:16 +08:00
|
|
|
|
|
|
|
|
|
|
// 监听 tab 切换,如果是 qxd 模式,加载站点列表
|
|
|
|
|
|
watch(
|
|
|
|
|
|
() => currentActiveKey.value,
|
|
|
|
|
|
activeKey => {
|
|
|
|
|
|
const code = getTabCode(activeKey);
|
|
|
|
|
|
if (code && qxdConfigMap[code]) {
|
|
|
|
|
|
loadQxdStationList(activeKey);
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
{ immediate: true }
|
|
|
|
|
|
);
|
2026-05-08 19:11:10 +08:00
|
|
|
|
// 监听内部 tab 切换
|
|
|
|
|
|
const onTabChange = (key: string) => {
|
|
|
|
|
|
currentActiveKey.value = key;
|
|
|
|
|
|
// 通知父组件更新 activeKey (支持 v-model)
|
|
|
|
|
|
// 通知父组件发生了切换事件 (用于业务逻辑,如加载数据)
|
2026-06-05 16:10:14 +08:00
|
|
|
|
emit('change', key);
|
2026-05-08 19:11:10 +08:00
|
|
|
|
};
|
2026-05-08 14:15:44 +08:00
|
|
|
|
|
|
|
|
|
|
// 关闭弹窗
|
|
|
|
|
|
const handleClose = () => {
|
2026-06-05 16:10:14 +08:00
|
|
|
|
emit('update:visible', false);
|
2026-06-12 16:59:35 +08:00
|
|
|
|
modelStore.params = {
|
|
|
|
|
|
sttp: 'eng',
|
|
|
|
|
|
stcd: '',
|
|
|
|
|
|
date: '',
|
|
|
|
|
|
show: true,
|
|
|
|
|
|
enfc: '0',
|
|
|
|
|
|
eqtp: '',
|
|
|
|
|
|
baseId: '',
|
|
|
|
|
|
sttpCode: '',
|
|
|
|
|
|
sttpMap: ''
|
|
|
|
|
|
};
|
2026-06-03 18:25:57 +08:00
|
|
|
|
// 清理状态,避免影响下次打开
|
|
|
|
|
|
modelStore.showStcdSelector = false;
|
|
|
|
|
|
modelStore.stcdOptions = [];
|
2026-06-10 15:45:16 +08:00
|
|
|
|
// 清理qxd模式状态
|
|
|
|
|
|
qxdStationOptions.value = [];
|
|
|
|
|
|
qxdSelectedStcd.value = '';
|
|
|
|
|
|
qxdSelectedStcdWq.value = '';
|
|
|
|
|
|
qxdSelectedStcdZq.value = '';
|
|
|
|
|
|
qxdLoadedCodes.value = new Set();
|
2026-06-12 16:59:35 +08:00
|
|
|
|
// 清理电站专题状态
|
|
|
|
|
|
hasPowerStatData.value = false;
|
|
|
|
|
|
modelStore.verticalWaterStcd = '';
|
|
|
|
|
|
modelStore.aiSites = [];
|
|
|
|
|
|
modelStore.wtConfig = {};
|
|
|
|
|
|
modelStore.wqShow = false;
|
|
|
|
|
|
modelStore.fishTabInfo = null;
|
2026-05-08 14:15:44 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 为了方便模板中使用,将 props.data 暴露给模板
|
|
|
|
|
|
const modalData = ref(props.data);
|
2026-05-08 19:11:10 +08:00
|
|
|
|
watch(
|
|
|
|
|
|
() => props.data,
|
2026-06-05 16:10:14 +08:00
|
|
|
|
newVal => {
|
2026-05-08 19:11:10 +08:00
|
|
|
|
modalData.value = newVal;
|
|
|
|
|
|
}
|
|
|
|
|
|
);
|
2026-06-03 18:25:57 +08:00
|
|
|
|
// 搜索过滤函数
|
|
|
|
|
|
const filterOption = (input: string, option: any) => {
|
|
|
|
|
|
return option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理测站切换
|
|
|
|
|
|
const handleStcdChange = (newStcd: string) => {
|
|
|
|
|
|
console.log('【测站切换】', newStcd);
|
|
|
|
|
|
// 由于 BasicInfo.vue 监听了 stcd 变化,这里只需更新 store
|
|
|
|
|
|
// 如果需要刷新所有 tab 的数据,可以在这里触发事件
|
|
|
|
|
|
};
|
2026-05-08 14:15:44 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
|
.map-modal {
|
2026-05-08 19:11:10 +08:00
|
|
|
|
.content {
|
|
|
|
|
|
min-height: 600px;
|
2026-05-08 14:15:44 +08:00
|
|
|
|
}
|
2026-06-12 16:59:35 +08:00
|
|
|
|
|
|
|
|
|
|
.loading-container {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
min-height: 400px;
|
|
|
|
|
|
}
|
2026-05-08 14:15:44 +08:00
|
|
|
|
}
|
2026-05-08 19:11:10 +08:00
|
|
|
|
</style>
|