基础信息配置

This commit is contained in:
王兴凯 2026-06-12 16:59:35 +08:00
parent 18efbcc41e
commit 849aeb8017
26 changed files with 4249 additions and 1197 deletions

View File

@ -22,6 +22,49 @@ export function getIdUrl(params: any) {
params
});
}
// 查询站点建设状态
export function getBuildState(data: any) {
return request({
url: '/api/dec-lygk-base-server/base/vmsstbprpt/GetKendoList',
method: 'post',
data: {
filter: data.filter,
select: ['bldsttCcode', 'engIwtCode', 'engDwtCode']
}
});
}
// 查询鱼类栖息地监测数据类型可用性
export function getFishTab(stcd: string) {
return request({
url: `/api/wmp-env-server/we/wer/getWeDefaultData`,
method: 'get',
params: { stcd }
});
}
// 检查水质站是否启用 AI 预测功能
export function checkAnalysisShow(data: any) {
return request({
url: '/api/dec-lygk-base-server/base/vmsstbprpt/GetKendoList',
method: 'post',
data
});
}
// 查询站点的关联子站点 (垂向水温、AI 识别)
export function getStInfoByStcd(params: any) {
return request({
url: '/api/dec-lygk-base-server/base/msstbprpt/getStInfoByStcd',
method: 'get',
params
});
}
// 检查电站是否有专题配置数据
export function checkPowerStationTopic(data: any) {
return request({
url: '/api/wmp-sys-server/sys/psbmodulelbb/GetKendoList',
method: 'post',
data
});
}
// 全景影像
export function getPanoramaList(data: any) {
return request({
@ -33,7 +76,7 @@ export function getPanoramaList(data: any) {
// 实时视频
export function getVideoList(data: any) {
return request({
url: '/vd/vmsstbprpt/GetKendoList',
url: '/api/dec-lygk-base-server/base/msstbprpt/GetKendoList',
method: 'post',
data
});

View File

@ -36,7 +36,6 @@
<script setup lang="ts">
import { ref, computed, onMounted, watch, nextTick, h, useSlots } from 'vue';
import { Tooltip } from 'ant-design-vue';
import { calcTableScrollY } from '@/utils/index';
// --- Types ---
@ -381,29 +380,12 @@ const enhancedColumns = computed(() => {
};
}
// ellipsis tooltip
// ellipsis
if (!props.enableEllipsis) return col;
return {
...col,
ellipsis: true,
customRender: ({ text }: any) => {
const content = String(text ?? props.emptyPlaceholder);
return h(Tooltip, { title: content }, () =>
h(
'div',
{
class: 'table-cell-ellipsis',
style: {
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis'
}
},
content
)
);
}
ellipsis: true
};
});
});

View File

@ -2222,8 +2222,7 @@ const FPPointColumns5: Array<any> = [
type: 'date',
format: 'YYYY-MM-DD',
url: ''
},
}
];
//鱼类增殖站 基础信息
const FBPointColumns: Array<any> = [
@ -3458,6 +3457,697 @@ const DwOnePointColumns: Array<any> = [
url: ''
}
];
const EQPointColumns2: Array<any> = [
{
name: '基本属性',
visible: false,
ruleTips: '',
type: '',
url: ''
},
{
name: '设施名称',
filed: 'stnm',
visible: true,
type: 'input',
url: ''
},
{
name: '站址',
filed: 'stlc',
visible: true,
type: 'select',
url: ''
},
{
name: '所属流域',
filed: 'hbrvcdName',
visible: true,
type: 'select',
url: ''
},
{
name: '经度(°)',
filed: 'lgtd',
visible: true,
type: 'number',
toFixed: 6,
url: ''
},
{
name: '纬度(°)',
filed: 'lttd',
visible: true,
type: 'number',
toFixed: 6,
url: ''
},
{
name: '所属电站',
filed: 'ennm',
visible: true,
type: 'select',
url: ''
},
{
name: '生态放流闸',
visible: false,
ruleTips: '',
type: '',
url: ''
},
{
name: '开工日期',
filed: 'ststdt',
visible: true,
type: 'date',
format: 'YYYY-MM-DD',
url: ''
},
{
name: '建成日期',
filed: 'jcdt',
visible: true,
type: 'date',
format: 'YYYY-MM-DD',
url: ''
},
{
name: '孔口尺寸(m)',
filed: 'flksz',
visible: true,
type: 'input',
url: ''
},
{
name: '进水口底板高程(m)',
filed: 'jskgc',
visible: true,
type: 'input',
url: ''
},
{
name: '出水口底板高程(m)',
filed: 'outflrelev',
visible: true,
type: 'input',
url: ''
},
{
name: '死水位时保证流量(m³/s)',
filed: 'ddzgq',
visible: true,
type: 'input',
url: ''
},
{
name: '最大泄放流量(m³/s)',
filed: 'flkq',
visible: true,
type: 'input',
url: ''
},
{
name: '投资(亿元)',
filed: 'inv',
visible: true,
type: 'number',
toFixed: 6,
url: ''
},
{
name: '投资是否计入工程主体',
filed: 'invinmn',
visible: true,
type: 'select',
url: ''
},
{
name: '结构形式',
filed: 'frntwlltyp',
visible: true,
type: 'select',
url: ''
}
];
const EQPointColumns5: Array<any> = [
{
name: '基本属性',
visible: false,
ruleTips: '',
type: '',
url: ''
},
{
name: '设施名称',
filed: 'stnm',
visible: true,
type: 'input',
url: ''
},
{
name: '站址',
filed: 'stlc',
visible: true,
type: 'select',
url: ''
},
{
name: '所属流域',
filed: 'hbrvcdName',
visible: true,
type: 'select',
url: ''
},
{
name: '经度(°)',
filed: 'lgtd',
visible: true,
type: 'number',
toFixed: 6,
url: ''
},
{
name: '纬度(°)',
filed: 'lttd',
visible: true,
type: 'number',
toFixed: 6,
url: ''
},
{
name: '所属电站',
filed: 'ennm',
visible: true,
type: 'select',
url: ''
},
{
name: '基荷发电',
visible: false,
ruleTips: '',
type: '',
url: ''
},
{
name: '开工日期',
filed: 'ststdt',
visible: true,
type: 'date',
format: 'YYYY-MM-DD',
url: ''
},
{
name: '建成日期',
filed: 'jcdt',
visible: true,
type: 'date',
format: 'YYYY-MM-DD',
url: ''
},
{
name: '基荷发电工况(MW)',
filed: 'jhfdgk',
visible: true,
type: 'input',
url: ''
},
{
name: '发电流量(m³/s)',
filed: 'fdll',
visible: true,
type: 'input',
url: ''
},
{
name: '进水口底板高程(m)',
filed: 'jskgc',
visible: true,
type: 'input',
url: ''
},
{
name: '出水口底板高程(m)',
filed: 'outflrelev',
visible: true,
type: 'input',
url: ''
}
];
const EQPointColumns3: Array<any> = [
{
name: '基本属性',
visible: false,
ruleTips: '',
type: '',
url: ''
},
{
name: '设施名称',
filed: 'stnm',
visible: true,
type: 'input',
url: ''
},
{
name: '站址',
filed: 'stlc',
visible: true,
type: 'select',
url: ''
},
{
name: '所属流域',
filed: 'hbrvcdName',
visible: true,
type: 'select',
url: ''
},
{
name: '经度(°)',
filed: 'lgtd',
visible: true,
type: 'number',
toFixed: 6,
url: ''
},
{
name: '纬度(°)',
filed: 'lttd',
visible: true,
type: 'number',
toFixed: 6,
url: ''
},
{
name: '所属电站',
filed: 'ennm',
visible: true,
type: 'select',
url: ''
},
{
name: '生态放流洞',
visible: false,
ruleTips: '',
type: '',
url: ''
},
{
name: '开工日期',
filed: 'ststdt',
visible: true,
type: 'date',
format: 'YYYY-MM-DD',
url: ''
},
{
name: '建成日期',
filed: 'jcdt',
visible: true,
type: 'date',
format: 'YYYY-MM-DD',
url: ''
},
{
name: '孔口尺寸(m)',
filed: 'flksz',
visible: true,
type: 'input',
url: ''
},
{
name: '进水口底板高程(m)',
filed: 'jskgc',
visible: true,
type: 'input',
url: ''
},
{
name: '出水口底板高程(m)',
filed: 'outflrelev',
visible: true,
type: 'input',
url: ''
},
{
name: '死水位时保证流量(m³/s)',
filed: 'ddzgq',
visible: true,
type: 'input',
url: ''
},
{
name: '最大泄放流量(m³/s)',
filed: 'flkq',
visible: true,
type: 'input',
url: ''
},
{
name: '投资(亿元)',
filed: 'inv',
visible: true,
type: 'number',
toFixed: 6,
url: ''
},
{
name: '投资是否计入工程主体',
filed: 'invinmn',
visible: true,
type: 'select',
url: ''
},
{
name: '结构形式',
filed: 'frntwlltyp',
visible: true,
type: 'select',
url: ''
}
];
const EQPointColumns4: Array<any> = [
{
name: '基本属性',
visible: false,
ruleTips: '',
type: '',
url: ''
},
{
name: '设施名称',
filed: 'stnm',
visible: true,
type: 'input',
url: ''
},
{
name: '站址',
filed: 'stlc',
visible: true,
type: 'select',
url: ''
},
{
name: '所属流域',
filed: 'hbrvcdName',
visible: true,
type: 'select',
url: ''
},
{
name: '经度(°)',
filed: 'lgtd',
visible: true,
type: 'number',
toFixed: 6,
url: ''
},
{
name: '纬度(°)',
filed: 'lttd',
visible: true,
type: 'number',
toFixed: 6,
url: ''
},
{
name: '所属电站',
filed: 'ennm',
visible: true,
type: 'select',
url: ''
},
{
name: '生态放流管',
visible: false,
ruleTips: '',
type: '',
url: ''
},
{
name: '开工日期',
filed: 'ststdt',
visible: true,
type: 'date',
format: 'YYYY-MM-DD',
url: ''
},
{
name: '建成日期',
filed: 'jcdt',
visible: true,
type: 'date',
format: 'YYYY-MM-DD',
url: ''
},
{
name: '孔口尺寸(m)',
filed: 'flksz',
visible: true,
type: 'input',
url: ''
},
{
name: '进水口底板高程(m)',
filed: 'jskgc',
visible: true,
type: 'input',
url: ''
},
{
name: '出水口底板高程(m)',
filed: 'outflrelev',
visible: true,
type: 'input',
url: ''
},
{
name: '死水位时保证流量(m³/s)',
filed: 'ddzgq',
visible: true,
type: 'input',
url: ''
},
{
name: '最大泄放流量(m³/s)',
filed: 'flkq',
visible: true,
type: 'input',
url: ''
},
{
name: '投资(亿元)',
filed: 'inv',
visible: true,
type: 'number',
toFixed: 6,
url: ''
},
{
name: '投资是否计入工程主体',
filed: 'invinmn',
visible: true,
type: 'select',
url: ''
},
{
name: '结构形式',
filed: 'frntwlltyp',
visible: true,
type: 'select',
url: ''
}
];
const EQPointColumns1: Array<any> = [
{
name: '基本属性',
visible: false,
ruleTips: '',
type: '',
url: ''
},
{
name: '设施名称',
filed: 'stnm',
visible: true,
type: 'input',
url: ''
},
{
name: '站址',
filed: 'stlc',
visible: true,
type: 'select',
url: ''
},
{
name: '所属流域',
filed: 'hbrvcdName',
visible: true,
type: 'select',
url: ''
},
{
name: '经度(°)',
filed: 'lgtd',
visible: true,
type: 'number',
toFixed: 6,
url: ''
},
{
name: '纬度(°)',
filed: 'lttd',
visible: true,
type: 'number',
toFixed: 6,
url: ''
},
{
name: '所属电站',
filed: 'ennm',
visible: true,
type: 'select',
url: ''
},
{
name: '生态放流孔',
visible: false,
ruleTips: '',
type: '',
url: ''
},
{
name: '开工日期',
filed: 'ststdt',
visible: true,
type: 'date',
format: 'YYYY-MM-DD',
url: ''
},
{
name: '建成日期',
filed: 'jcdt',
visible: true,
type: 'date',
format: 'YYYY-MM-DD',
url: ''
},
{
name: '孔口尺寸(m)',
filed: 'flksz',
visible: true,
type: 'input',
url: ''
},
{
name: '进水口底板高程(m)',
filed: 'jskgc',
visible: true,
type: 'input',
url: ''
},
{
name: '出水口底板高程(m)',
filed: 'outflrelev',
visible: true,
type: 'input',
url: ''
},
{
name: '死水位时保证流量(m³/s)',
filed: 'ddzgq',
visible: true,
type: 'input',
url: ''
},
{
name: '最大泄放流量(m³/s)',
filed: 'flkq',
visible: true,
type: 'input',
url: ''
},
{
name: '投资(亿元)',
filed: 'inv',
visible: true,
type: 'number',
toFixed: 6,
url: ''
},
{
name: '投资是否计入工程主体',
filed: 'invinmn',
visible: true,
type: 'select',
url: ''
},
{
name: '结构形式',
filed: 'frntwlltyp',
visible: true,
type: 'select',
url: ''
}
];
const EQPointColumns7: Array<any> = [
{
name: '基本属性',
visible: false,
ruleTips: '',
type: '',
url: ''
},
{
name: '设施名称',
filed: 'stnm',
visible: true,
type: 'input',
url: ''
},
{
name: '站址',
filed: 'stlc',
visible: true,
type: 'select',
url: ''
},
{
name: '所属流域',
filed: 'hbrvcdName',
visible: true,
type: 'select',
url: ''
},
{
name: '经度(°)',
filed: 'lgtd',
visible: true,
type: 'number',
toFixed: 6,
url: ''
},
{
name: '纬度(°)',
filed: 'lttd',
visible: true,
type: 'number',
toFixed: 6,
url: ''
},
{
name: '所属电站',
filed: 'ennm',
visible: true,
type: 'select',
url: ''
},
];
//阶段属性
const basicFilterColumns: Array<any> = [
{
@ -4183,6 +4873,12 @@ export {
DwFivePointColumns,
DwSixPointColumns,
DwOnePointColumns,
EQPointColumns2,
EQPointColumns5,
EQPointColumns3,
EQPointColumns4,
EQPointColumns1,
EQPointColumns7,
StinfoAiVidoPointColumns,
basicFilterColumns,
tabsWithTwoColumns,

View File

@ -128,6 +128,12 @@ import {
FBPointColumns,
VaPointColumns,
VPPointColumns,
EQPointColumns1,
EQPointColumns2,
EQPointColumns5,
EQPointColumns3,
EQPointColumns4,
EQPointColumns7,
wePointColumns,
waPointColumns,
DwPointColumns,
@ -230,6 +236,30 @@ const columnsConfig = ref([
{
type: 'VP',
columns: VPPointColumns
},
{
type: 'EQ_1',
columns: EQPointColumns1
},
{
type: 'EQ_2',
columns: EQPointColumns2
},
{
type: 'EQ_5',
columns: EQPointColumns5
},
{
type: 'EQ_3',
columns: EQPointColumns3
},
{
type: 'EQ_4',
columns: EQPointColumns4
},
{
type: 'EQ_7',
columns: EQPointColumns7
},
{
type: 'WE',
@ -243,6 +273,10 @@ const columnsConfig = ref([
type: 'VD_FBFM',
columns: StinfoAiVidoPointColumns
},
{
type: 'VD',
columns: StinfoAiVidoPointColumns
},
{
type: 'eng_alarm_point',
columns: BasicColumns
@ -301,7 +335,11 @@ const getData = async () => {
let columns = [];
columns = columnsConfig.value.find(
item => item.type == modelStore.params.sttp
item =>
item.type ==
(modelStore.params.sttp == 'EQ'
? modelStore.params.anchoPointState
: modelStore.params.sttp)
).columns;
columns.forEach(item => {

View File

@ -1,7 +1,7 @@
<template>
<a-modal
:open="visible"
:title="title"
:title="title + ' ' + '详情信息'"
width="80vw"
:footer="null"
:closable="true"
@ -33,21 +33,33 @@
>
</a-select>
</div>
<a-tabs :active-key="currentActiveKey" @change="onTabChange">
<!-- 加载状态提示 -->
<div v-if="isLoading" class="loading-container">
<a-spin tip="加载中..." />
</div>
<!-- Tabs 区域 - 等待加载完成后显示 -->
<a-tabs v-else :active-key="currentActiveKey" @change="onTabChange">
<a-tab-pane v-for="tab in tabsConfig" :key="tab.key" :tab="tab.name">
</a-tab-pane>
<template #rightExtra v-if="anchor.sttp == 'ENG' || anchor.sttp == 'eng'">
<a-tooltip :title="!isEngConfig ? '' : '该电站无专题配置'">
<a-button type="primary" :disabled="isEngConfig">
<a-tooltip :title="!hasPowerStatData ? '该电站无专题配置' : ''">
<a-button
type="primary"
:disabled="!hasPowerStatData"
@click="gotoEngTopic"
>
<i class="icon iconfont icon-topic mr-[5px]"></i>
电站专题
</a-button></a-tooltip
>
</template>
</a-tabs>
<!-- 内容区域 - 使用动态组件 + keep-alive 实现按需加载和缓存 -->
<keep-alive>
<div class="content">
<div v-if="!isLoading" class="content">
<div class="content-wrapper" v-show="isQxdMode(currentActiveKey)">
测站
<a-select
@ -90,11 +102,13 @@
? qxdSelectedStcd
: ''
"
:wt-config="modelStore.wtConfig"
/>
<!-- 监测数据 - 垂向水温 -->
<VerticalWaterTemperature
v-show="currentActiveKey === 'VerticalWaterTemperature'"
:is-active="currentActiveKey === 'VerticalWaterTemperature'"
:stcd="modelStore.verticalWaterStcd || modelStore.params.stcd"
/>
<!-- 监测数据 - 水质 -->
<WaterQuality
@ -106,6 +120,7 @@
? qxdSelectedStcdWq
: ''
"
:wq-show="modelStore.wqShow"
/>
<!-- 流量监测 -->
<FlowMeasure
@ -176,13 +191,445 @@ import { handleTabs } from './setting.config';
import {
getMonitorDataWt,
getMonitorDataWq,
getMonitorDataZq
getMonitorDataZq,
getBuildState,
getFishTab,
checkAnalysisShow,
getStInfoByStcd,
getVideoList,
getMonitorDataWaterTempPowerStation,
getMonitorDataWaterTempPowerStation2,
checkPowerStationTopic
} from '@/api/mapModal';
// import { useRouter } from 'vue-router';
const modelStore = useModelStore();
const tabsConfig = ref([]);
//
const isEngConfig = ref(true);
// 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; //
}
};
// ==================== qxd ====================
// qxd
@ -361,7 +808,7 @@ const emit = defineEmits<{
// activeKey
const currentActiveKey = ref<string>('');
const anchor = ref<string>('');
const anchor = ref<any>('');
// activeKey
watch(
@ -375,20 +822,27 @@ watch(
);
watch(
() => modelStore.params,
newVal => {
async newVal => {
if (!newVal || Object.keys(newVal).length === 0) return;
console.log(newVal);
anchor.value = newVal;
let params = newVal;
if (['VD', 'WTRV', 'ZQ', 'WQ'].includes(params?.sttpCode)) {
params.sttp = params.sttpCode;
}else
if (['ENG_ALARM'].includes(params?.sttpMap)) {
} else if (['ENG_ALARM'].includes(params?.sttpMap)) {
params.sttp = params.sttpMap;
}
tabsConfig.value = handleTabs({ ...params });
let value = tabsConfig.value.find((item: any) => item.default);
currentActiveKey.value = value?.key;
//
if (params?.sttp?.toUpperCase() === 'ENG') {
checkPowerStationTopicData(params.stcd);
}
// Tab
applyTabFilters(params);
},
{ deep: true, immediate: true }
);
@ -415,7 +869,17 @@ const onTabChange = (key: string) => {
//
const handleClose = () => {
emit('update:visible', false);
modelStore.params = {};
modelStore.params = {
sttp: 'eng',
stcd: '',
date: '',
show: true,
enfc: '0',
eqtp: '',
baseId: '',
sttpCode: '',
sttpMap: ''
};
// ,
modelStore.showStcdSelector = false;
modelStore.stcdOptions = [];
@ -425,6 +889,13 @@ const handleClose = () => {
qxdSelectedStcdWq.value = '';
qxdSelectedStcdZq.value = '';
qxdLoadedCodes.value = new Set();
//
hasPowerStatData.value = false;
modelStore.verticalWaterStcd = '';
modelStore.aiSites = [];
modelStore.wtConfig = {};
modelStore.wqShow = false;
modelStore.fishTabInfo = null;
};
// 便使 props.data
@ -453,5 +924,12 @@ const handleStcdChange = (newStcd: string) => {
.content {
min-height: 600px;
}
.loading-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 400px;
}
}
</style>

View File

@ -208,131 +208,60 @@ const ENGEQTabs: Array<any> = [
// ].filter(Boolean)
// //生态流量泄放设施 √
// const EQTabs: Array<any> = [
// {
// name: '基础信息',
// key: 'basicInfo',
// type: 'basic',
// url: '/bbi/siteBipc/getSiteBasicInfo'
// },
// {
// name: '实时视频',
// key: 'videoInfo',
// type: 'video',
// url: '/video/dataStcdFrame/getVideoMonitorList'
// },
// // {
// // name: '全景影像',
// // key: 'panoramaInfo',
// // type: 'panorama'
// // },
// {
// name: '监测数据',
// key: 'flowDischarge',
// type: 'FlowDischarge'
// }
// ]
// 过鱼设施 √
const FPTabs: Array<any> =
// Session.getAppCode() === 'hbb'
// ? [
// {
// name: '基础信息',
// key: 'basicInfo',
// type: 'basic',
// url: '/bbi/siteBipc/getSiteBasicInfo',
// code: 'gyss.tabs.jcxx'
// },
// {
// name: '实时视频',
// key: 'videoInfo',
// type: 'video',
// url: '/video/dataStcdFrame/getVideoMonitorList',
// code: 'gyss.tabs.sssp'
// },
// {
// name: '在线监测数据',
// key: 'FishFacilityMonitorData', //Normal
// type: 'FishFacilityMonitorData', //Normal
// code: 'gyss.tabs.jcsj',
// // tabs: [
// // {
// // name: '',
// // type: 'table',
// // tableUrl: getUrl('/wmp-env-server/env/fp/fpssTable/GetKendoListCust'),
// // hiddenChart: true,
// // hiddenTabs: true,
// // filter: NormalDatePickerFilter
// // }
// // ]
// },
// {
// name: '运行情况',
// key: 'FishFacilityRunState', //Normal1
// type: 'FishFacilityRunState', //Normal
// code: 'gyss.tabs.yxqk',
// // tabs: [
// // {
// // name: '',
// // type: 'table',
// // tableUrl: getUrl('/wmp-env-server/env/fp/run/secondRun/GetKendoListCust'),
// // hiddenChart: true,
// // hiddenTabs: true,
// // filter: NormalFishFilter
// // }
// // ]
// },
// {
// name: '综合分析',
// key: 'FishZHFX',
// type: 'FishZHFX',
// // tabs: [
// // {
// // name: '',
// // type: 'table',
// // tableUrl: getUrl('/wmp-env-server/env/fp/run/secondRun/GetKendoListCust'),
// // hiddenChart: true,
// // hiddenTabs: true,
// // filter: NormalFishFilter
// // }
// // ]
// },
// {
// name: 'AI运行识别',
// key: 'AIYXSB',
// type: 'AIYXSB',
// }
// ]
// :
[
const EQTabs: Array<any> = [
{
name: '基础信息',
key: 'basicInfo',
type: 'basic',
url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo'
// code: 'gyss.tabs.jcxx'
url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo',
default: true // 默认显示
},
{
name: '实时视频',
key: 'videoInfo',
type: 'video',
url: '/video/dataStcdFrame/getVideoMonitorList'
},
// {
// name: '实时视频',
// key: 'videoInfo',
// type: 'video',
// url: '/video/dataStcdFrame/getVideoMonitorList',
// code: 'gyss.tabs.sssp'
// }
// name: '全景影像',
// key: 'panoramaInfo',
// type: 'panorama'
// },
{
name: '监测数据',
key: 'flowDischarge',
type: 'FlowDischarge'
}
];
// 过鱼设施 √
const FPTabs: Array<any> = [
{
name: '基础信息',
key: 'basicInfo',
type: 'basic',
url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo',
code: 'gyss.tabs.jcxx'
},
{
name: '实时视频',
key: 'videoInfo',
type: 'video',
url: '/video/dataStcdFrame/getVideoMonitorList',
code: 'gyss.tabs.sssp'
},
{
name: '在线监测数据',
key: 'FishFacilityMonitorData', //Normal
type: 'FishFacilityMonitorData', //Normal
code: 'gyss.tabs.jcsj',
// 默认显示
tabs: [
{
name: '',
type: 'table',
tableUrl: '/wmp-env-server/env/fp/fpssTable/GetKendoListCust',
// tableUrl: getUrl('/wmp-env-server/env/fp/fpssTable/GetKendoListCust'),//getUrl
hiddenChart: true,
hiddenTabs: true
// filter: NormalDatePickerFilter
// filter: NormalDatePickerFilter // 没有
}
]
},
@ -341,8 +270,23 @@ const FPTabs: Array<any> =
key: 'FishFacilityRunState', //Normal1
type: 'FishFacilityRunState', //Normal
code: 'gyss.tabs.yxqk',
default: true
// tabs: [
default: true, // 默认显示
tabs: [
{
name: '',
type: 'table',
// tableUrl: getUrl('/wmp-env-server/env/fp/run/secondRun/GetKendoListCust'),
hiddenChart: true,
hiddenTabs: true
// filter: NormalFishFilter // 没有
}
]
},
{
name: '综合分析',
key: 'FishZHFX',
type: 'FishZHFX'
// tabs: [ 线上同步注释
// {
// name: '',
// type: 'table',
@ -354,12 +298,11 @@ const FPTabs: Array<any> =
// ]
},
{
name: '综合分析',
key: 'FishZHFX',
type: 'FishZHFX',
code: 'gyss.tabs.zhfx'
name: 'AI运行识别',
key: 'AIYXSB',
type: 'AIYXSB'
}
];
];
// // 过鱼设施在建状态
const FPTabs1: Array<any> = [
@ -389,7 +332,7 @@ const FBTabs: Array<any> = [
name: '基础信息',
key: 'basicInfo',
type: 'basic',
url: '/bbi/siteBipc/getSiteBasicInfo'
url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo'
},
{
name: '运行数据',
@ -724,7 +667,7 @@ const WETabs: Array<any> = [
name: '基础信息',
key: 'basicInfo',
type: 'basic',
url: '/bbi/siteBipc/getSiteBasicInfo',
url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo',
default: true // 默认显示
},
{
@ -857,7 +800,7 @@ const VPTabs: Array<any> = [
name: '基础信息',
key: 'basicInfo',
type: 'basic',
url: '/bbi/siteBipc/getSiteBasicInfo',
url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo',
default: true // 默认显示
},
// {
@ -940,7 +883,7 @@ const VATabs: Array<any> = [
name: '基础信息',
key: 'basicInfo',
type: 'basic',
url: '/bbi/siteBipc/getSiteBasicInfo',
url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo',
default: true // 默认显示
},
// {
@ -1067,7 +1010,7 @@ const WATabs: Array<any> = [
name: '基础信息',
key: 'basicInfo',
type: 'basic',
url: '/bbi/siteBipc/getSiteBasicInfo',
url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo',
default: true // 默认显示
},
{
@ -1104,11 +1047,19 @@ const handleTabs = (modaldata: any) => {
return WQFBTabs;
case 'WQ':
const _tabs = [...WQTabs];
if (modaldata?.dtinType == 2 || modaldata?.dtinType == 1)
if (modaldata?.dtinType == 2 || modaldata?.dtinType == 1) {
_tabs.splice(2, 1); //国家站 人工站把视频tab去除
}
return _tabs;
case 'FH':
return FHTabs;
let arr = [...FHTabs];
if (modaldata?.bldstt == 2 || modaldata?.bldstt == 1) {
console.log('modaldata', modaldata);
arr =[ arr[0]]; //国家站 人工站把视频tab去除
}
return arr;
case 'FH_ZQ_POINT':
return FLOWTabs;
case 'FP_POINT':
@ -1124,6 +1075,7 @@ const handleTabs = (modaldata: any) => {
case 'WVA':
return WATabs;
case 'VD_FBFM':
case 'VD':
return videoTabs;
case 'ENG_ALARM_POINT':
return DZGJ;
@ -1151,8 +1103,8 @@ const handleTabs = (modaldata: any) => {
// }
case 'ENG_ALARM':
return DZGJ;
// case 'EQ':
// return EQTabs
case 'EQ':
return EQTabs;
case 'DW':
case 'DW_1':
case 'DW_2':
@ -1160,58 +1112,37 @@ const handleTabs = (modaldata: any) => {
case 'DW_4':
case 'DW_5':
return DWTabs;
case 'FP_1': //todo后续再删除多余代码
return FPTabs.filter(item => item.name !== '在线监测数据');
case 'FP': //todo后续再删除多余代码
case 'FP_1': //todo后续再删除多余代码
// case "FP_2": //todo后续再删除多余代码
case 'FP_3': //todo后续再删除多余代码
case 'FP_4': //todo后续再删除多余代码
// case "FP_5": //todo后续再删除多余代码
// // if (Session.getAppCode() === 'hbb') {
// mway为2的时侯显示在线监测数据
if (
modaldata.bldsttCcode == '1' ||
modaldata.bldsttCcode == '0' ||
modaldata.bldstt == '1' ||
modaldata.bldstt == '0' ||
modaldata.bldstt == '2'
modaldata.bldstt == '0'
) {
console.log(1);
return [
...FPTabs1 //建设情况
];
} else {
console.log(2);
if (modaldata.mway != 2) {
console.log(3);
return FPTabs.filter(item => item.name !== '在线监测数据');
} else {
console.log(4);
return [
...FPTabs //有监测数据
];
}
}
// } else {
// if (modaldata.bldsttCcode == '1' || modaldata.bldsttCcode == '0' || modaldata.bldstt == '1' || modaldata.bldstt == '0') {
// return [
// ...FPTabs1
// // {
// // name: "系统运行记录",
// // key: "FishSystemRunState", //Normal1
// // type: "FishSystemRunState", //Normal
// // tabs: []
// // }
// ]
// } else {
// return [
// ...FPTabs
// // {
// // name: "系统运行记录",
// // key: "FishSystemRunState", //Normal1
// // type: "FishSystemRunState", //Normal
// // tabs: []
// // }
// ]
// }
// }
case 'FP_2': //todo后续再删除多余代码
case 'FP_5': //todo后续再删除多余代码
if (

View File

@ -493,7 +493,7 @@ const initChart = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "WT";
modelStore.params.enfc = '1';
modelStore.title = stnm + "详情信息";
modelStore.title = stnm ;
// modelStore.isBasicEdit = true;
modelStore.params.stcd = stcd;
@ -643,7 +643,7 @@ const handleChartClick = (params: any) => {
timeRange: [startTime, endTime]
} as any;
modelStore.title = currentStnm ? `${currentStnm} 详情信息` : '详情信息';
modelStore.title = currentStnm ? `${currentStnm} ` : '';
modelStore.tabList = handleTabs(modelStore.params);
modelStore.modalVisible = true;
});

View File

@ -462,7 +462,7 @@ const handleViewDetail = (record: any, type: string) => {
} else if (type === 'ENG') {
modelStore.modalVisible = true;
modelStore.params.sttp = "ENG";
modelStore.title = record.stnm + " 详情信息";
modelStore.title = record.stnm;
modelStore.params.stcd = record.rstcd;
}

View File

@ -64,7 +64,7 @@ const customTransform = (res: any) => {
const handleViewDetail = (record: any) => {
modelStore.modalVisible = true;
modelStore.params.sttp = "VD_FBFM";
modelStore.title = record.stnm + "详情信息";
modelStore.title = record.stnm ;
modelStore.params.stcd = record.stcd;
}
//

View File

@ -3,19 +3,38 @@
<!-- 搜索表单 -->
<a-form layout="inline" class="search-form">
<a-form-item label="设施类型">
<a-select v-model:value="filterOpts.dwtp" placeholder="请选择设施类型" style="width: 150px"
:options="facilityTypeOptions" />
<a-select
v-model:value="filterOpts.dwtp"
placeholder="请选择设施类型"
style="width: 150px"
:options="facilityTypeOptions"
/>
</a-form-item>
<a-form-item label="所属基地">
<a-select v-model:value="filterOpts.baseId" placeholder="请选择所属基地" style="width: 200px" show-search
:filter-option="filterOption" :options="jdInfoOpt" />
<a-select
v-model:value="filterOpts.baseId"
placeholder="请选择所属基地"
style="width: 200px"
show-search
:filter-option="filterOption"
:options="jdInfoOpt"
/>
</a-form-item>
<a-form-item label="建设状态">
<a-select v-model:value="filterOpts.bldstt" placeholder="请选择建设状态" style="width: 150px"
:options="buildStateOptions" />
<a-select
v-model:value="filterOpts.bldstt"
placeholder="请选择建设状态"
style="width: 150px"
:options="buildStateOptions"
/>
</a-form-item>
<a-form-item>
<a-input v-model:value="filterOpts.searchContent" placeholder="请输入设施名称" style="width: 200px" allow-clear />
<a-input
v-model:value="filterOpts.searchContent"
placeholder="请输入设施名称"
style="width: 200px"
allow-clear
/>
</a-form-item>
<a-form-item>
<a-space>
@ -34,8 +53,16 @@
</a-form>
<!-- 数据表格 -->
<BasicTable ref="tableRef" :scroll-y="400" :columns="columns" :list-url="vmsstbprptGetKendoList" :enable-sort="true"
:search-params="searchParams" :transform-data="customTransform" @sort-change="handleSortChange">
<BasicTable
ref="tableRef"
:scroll-y="400"
:columns="columns"
:list-url="fpVmsstbprptGetKendoList"
:enable-sort="true"
:search-params="searchParams"
:transform-data="customTransform"
@sort-change="handleSortChange"
>
<template #ennm="{ record }">
<a @click="handleViewDetail(record, 'dz')" class="text-link">
{{ record.ennm }}
@ -54,7 +81,7 @@
import { ref, computed, onMounted, nextTick } from 'vue';
import BasicTable from '@/components/BasicTable/index.vue';
// TODO: API - @/api/gyss
import { vmsstbprptGetKendoList } from '@/api/gyss';
import { fpVmsstbprptGetKendoList } from '@/api/gyss';
import { useModelStore } from '@/store/modules/model';
const modelStore = useModelStore();
@ -318,12 +345,16 @@ const handleViewDetail = (record: any, type: string) => {
if (type === 'dz') {
modelStore.modalVisible = true;
modelStore.params.sttp = 'ENG';
modelStore.title = record.ennm + ' 详情信息';
modelStore.title = record.ennm;
modelStore.params.stcd = record.rstcd;
} else {
// const sttpFullPath = 'ENV,ENVP,FP,FP_2,';
// 使 filter
const parts = record.sttpFullPath.split(',').filter(item => item.trim() !== '');
const lastValue = parts[parts.length - 1];
modelStore.modalVisible = true;
modelStore.params.sttp = 'fp_point';
modelStore.title = record.stnm + '详情信息';
modelStore.params.sttp = lastValue
modelStore.title = record.stnm;
modelStore.params.stcd = record.stcd;
}
// console.log('', record)

View File

@ -816,7 +816,7 @@ const handleViewDetail = (record: any) => {
});
modelStore.modalVisible = true;
modelStore.params.sttp = 'WT';
modelStore.title = stnm + '详情信息';
modelStore.title = stnm ;
modelStore.params.stcd = formValue.stcd;
};

View File

@ -21,7 +21,7 @@
</a-spin>
</SidePanelItem>
<!-- 弹框 -->
<a-modal v-model:open="modalVisible" :title="'水质监测工作开展情况'" :footer="null" width="1536px" @cancel="handleCloseModal">
<a-modal v-model:open="modalVisible" :title="'栖息地保护工作开展情况'" :footer="null" width="1536px" @cancel="handleCloseModal">
<QixidiheduanjianceqingkuangEJ v-if="currentFacility" :activeKey="currentFacility.sttpCode" :tabs="facilities"
:baseId="baseid" />
</a-modal>

View File

@ -347,24 +347,25 @@ const handleViewDetail = (record: any, type: any) => {
if (type == 'dz') {
modelStore.modalVisible = true;
modelStore.params.sttp = 'ENG';
modelStore.title = record.ennm + ' 详情信息';
modelStore.title = record.ennm;
modelStore.params.stcd = record.rstcd;
} else {
if (tabIndex.value == 'FH') {
modelStore.modalVisible = true;
modelStore.params.sttp = 'FH';
modelStore.title = record.stnm + ' 详情信息';
modelStore.title = record.stnm;
modelStore.params.stcd = record.stcd;
modelStore.params.bldstt = '2';
modelStore.params.show = false;
} else if (tabIndex.value == 'WTRV') {
modelStore.modalVisible = true;
modelStore.params.sttp = 'WT';
modelStore.title = record.stnm + ' 详情信息';
modelStore.title = record.stnm;
modelStore.params.stcd = record.stcd;
} else if (tabIndex.value == 'ZQ') {
modelStore.modalVisible = true;
modelStore.params.sttp = 'fh_zq_point';
modelStore.title = record.stnm + ' 详情信息';
modelStore.title = record.stnm;
modelStore.params.stcd = record.stcd;
} else if (tabIndex.value == 'VD') {
modelStore.modalVisible = true;

View File

@ -290,7 +290,7 @@ const handleHabitatClick = (record: any) => {
// TODO:
modelStore.modalVisible = true;
modelStore.params.sttp = 'FH';
modelStore.title = record.stnm + ' 详情信息';
modelStore.title = record.stnm;
modelStore.params.stcd = record.stcd;
modelStore.params.show = true;
};

View File

@ -0,0 +1,416 @@
<template>
<div class="stlldbqk_container">
<div class="stlldbqk_title">
<div>选择水电站:</div>
<a-select
v-model:value="from.baseId"
show-search
placeholder=" "
:options="jidiOptions"
:filter-option="filterOption"
@change="handleChange"
style="width: 200px; margin: 0px 10px"
></a-select>
<a-select
v-model:value="from.stcd"
show-search
placeholder="请选择电站"
:options="stcdOptions"
:filter-option="filterOption"
style="width: 200px"
></a-select>
<a-button type="primary" style="margin: 0px 10px" @click="Search()"
>搜索</a-button
>
<a-button @click="resetSearch()">重置</a-button>
</div>
<div class="table">
<BasicTable
ref="tableRef"
:columns="columns"
:scrollY="480"
:list-url="vmsstbprptGetKendoList"
:search-params="searchParams"
:transform-data="customTransform"
:enable-sort="true"
@sort-change="handleSortChange"
>
<template #dvtp="{ record }">
{{
record.dvtp == 2 ? '引水式' : record.dvtp == 3 ? '混合式' : '坝后式'
}}
</template>
<template #stindx="{ record }">
{{ record.dvtp == 2 ? '生态流量' : '出库流量' }}
</template>
<template #coenvwState="{ column, record }">
<a-tag :color="record.coenvwState > 0 ? 'success' : ''">
{{ record.coenvwState > 0 ? '在线' : '离线' }}
</a-tag>
</template>
<template #action="{ column, record }">
<a-button type="link" size="small" @click="handleView(record)"
>查看详情</a-button
>
</template>
</BasicTable>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, computed, onMounted, onUnmounted, watch, nextTick, h } from 'vue';
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
import { vmsstbprptGetKendoList } from '@/api/stll';
import BasicTable from '@/components/BasicTable/index.vue';
import { useModelStore } from '@/store/modules/model';
const modelStore = useModelStore();
const props = defineProps<{
baseId?: any;
titleData?: any;
}>();
const tableRef = ref();
const columns = ref([
{
title: '所属基地',
key: 'baseName',
dataIndex: 'baseName',
merge: true, //
visible: true
},
{
title: '电站名称',
key: 'stnm',
dataIndex: 'stnm',
visible: true
},
{
title: '开发方式',
key: 'dvtp',
dataIndex: 'dvtp',
visible: true,
slots: { customRender: 'dvtp' }
},
{
title: '生态流量站类型',
key: 'stindx',
dataIndex: 'stindx',
visible: true,
slots: { customRender: 'stindx' }
},
{
title: '建成时间',
key: 'jcdt',
dataIndex: 'jcdt',
visible: true,
sorter: true,
customRender: ({ record }: any) => {
const date = record.jcdt;
if (!date) return '-';
if (typeof date === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(date)) {
return date;
}
if (typeof date === 'string' && date.includes(' ')) {
return date.split(' ')[0];
}
return date;
}
},
{
title: '监测状态',
key: 'coenvwState',
dataIndex: 'coenvwState',
visible: true,
slots: { customRender: 'coenvwState' }
},
{
title: '操作',
key: 'action',
width: 120,
slots: { customRender: 'action' }
}
]);
const sort = {
sort: [
{
field: 'baseStepSort',
dir: 'asc'
},
{
field: 'hbrvcd',
dir: 'asc'
},
{
field: 'rstcdStepSort',
dir: 'asc'
},
{
field: 'siteStepSort',
dir: 'asc'
}
],
group: [],
select: [
'baseName',
'stnm',
'ennm',
'jcdt',
'stindx',
'coenvwState',
'sttpCode',
'stcd',
'rstcd',
'stCode',
'stName',
'dvtp'
],
groupResultFlat: false
};
const JidiSelectEventStore = useJidiSelectEventStore();
// JidiSelectEventStore.jidiData
let jidiOptions = computed(() => {
return [
...JidiSelectEventStore.jidiData.map((item: any) => ({
value: item.wbsCode,
label: item.wbsName
}))
];
});
const from = ref({
baseId: props.baseId || 'all',
stcd: ''
});
//
const sortInfo = ref<{ field: string; order: string | null }>({
field: '',
order: null
});
//
const searchParams = computed(() => {
let baseSort;
//
if (sortInfo.value.field && sortInfo.value.order) {
baseSort = [
{
field: sortInfo.value.field,
dir: sortInfo.value.order === 'ascend' ? 'asc' : 'desc'
}
];
} else {
baseSort = [
{ field: 'baseStepSort', dir: 'asc' },
{ field: 'hbrvcd', dir: 'asc' },
{ field: 'rstcdStepSort', dir: 'asc' },
{ field: 'siteStepSort', dir: 'asc' }
];
}
return {
sort: baseSort,
group: [],
select: [
'baseName',
'stnm',
'ennm',
'jcdt',
'stindx',
'coenvwState',
'sttpCode',
'stcd',
'rstcd',
'stCode',
'stName',
'dvtp'
],
groupResultFlat: false
};
});
// props.baseId from.value.baseId
watch(
() => props.baseId,
newBaseId => {
//
if (newBaseId && newBaseId !== from.value.baseId) {
from.value.baseId = newBaseId;
from.value.stcd = ''; //
// DOM
nextTick(() => {
handleChange(); //
Search(); //
});
}
},
{ immediate: false }
);
const filterOption = (input: string, option: any) => {
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};
const stcdOptions = ref([]);
const handleChange = async () => {
try {
let params = {
filter: {
logic: 'and',
filters: [
from.value.baseId != 'all'
? {
field: 'baseId',
operator: 'contains',
dataType: 'string',
value: from.value.baseId
}
: null,
{
field: 'sttpCode',
operator: 'eq',
dataType: 'string',
value: 'ENG'
}
].filter(Boolean)
},
sort: [
{
field: 'baseId',
dir: 'asc'
},
{
field: 'rvcdStepSort',
dir: 'asc'
},
{
field: 'rstcdStepSort',
dir: 'asc'
},
{
field: 'siteStepSort',
dir: 'asc'
}
],
select: ['stcd', 'stnm']
};
let res = await vmsstbprptGetKendoList(params);
if (res?.data?.success && res?.data?.data) {
let data = res.data.data;
stcdOptions.value = data.map((item: any) => ({
value: item.stcd,
label: item.stnm
}));
} else {
stcdOptions.value = [];
}
} catch (error) {
console.error('获取电站列表失败:', error);
stcdOptions.value = [];
}
};
const Search = () => {
let filters = [
from.value.stcd
? {
field: 'stcd',
operator: 'eq',
value: from.value.stcd
}
: null,
from.value.baseId != 'all'
? {
field: 'baseId',
operator: 'eq',
value: from.value.baseId
}
: null,
{
field: 'runState',
operator: 'eq',
value: 4
},
{
field: 'sttpCode',
operator: 'eq',
dataType: 'string',
value: props.titleData?.sttpCode || 'ENG'
},
{
field: 'DTIN',
operator: 'eq',
dataType: 'string',
value: 1
},
{
field: 'bldsttCcode',
operator: 'eq',
dataType: 'string',
value: 2
}
].filter(Boolean);
const filter = {
logic: 'and',
filters
};
tableRef.value?.getList(filter);
};
//
const handleSortChange = (info: {
field: string;
order: 'ascend' | 'descend' | null;
}) => {
sortInfo.value.field = info.field || '';
sortInfo.value.order = info.order || null;
// DOM BasicTable searchParams
nextTick(() => {
Search();
});
};
const resetSearch = () => {
from.value = {
baseId: 'all',
stcd: ''
};
Search();
};
//
const customTransform = (res: any) => {
return {
records: res?.data?.data || [],
total: res?.data?.total || 0
};
};
const handleView = (record: any) => {
modelStore.modalVisible = true;
modelStore.params.sttp = 'ENG';
modelStore.title = record.stnm;
modelStore.params.stcd = record.stcd;
modelStore.params.eqtp = 'QGC';
modelStore.filterStll = 'qecInterval';
};
onMounted(() => {
handleChange();
Search();
});
onUnmounted(() => {});
</script>
<style scoped lang="scss">
.stlldbqk_container {
width: 100%;
.stlldbqk_title {
width: 100%;
display: flex;
align-items: center;
margin-bottom: 10px;
}
.table {
width: 100%;
height: 560px;
}
}
</style>

View File

@ -0,0 +1,944 @@
<template>
<div class="stlldbqk-container">
<!-- 搜索表单 -->
<a-form layout="inline" class="search-form">
<a-form-item label="基地选择">
<a-select
v-model:value="params.qid"
placeholder="请选择基地"
style="width: 200px"
show-search
:filter-option="filterOption"
:options="jidiOptions"
/>
</a-form-item>
<a-form-item label="规则类型">
<a-select
v-model:value="params.key"
placeholder="请选择规则类型"
style="width: 180px"
:options="ruleTypeOptions"
/>
</a-form-item>
<a-form-item label="时间维度">
<a-select
v-model:value="params.timeType"
placeholder="请选择时间维度"
style="width: 120px"
:options="timeTypeOptions"
/>
</a-form-item>
<a-form-item label="日期范围">
<a-range-picker
v-model:value="dateRange"
:allow-clear="false"
format="YYYY-MM-DD"
style="width: 360px"
/>
</a-form-item>
<a-form-item>
<a-space>
<a-button type="primary" @click="handleSearch">查询</a-button>
</a-space>
</a-form-item>
</a-form>
<!-- Tabs 标签页 -->
<a-tabs
v-if="tabList.length > 0"
v-model:activeKey="ecoFlowType"
class="tab-style"
@change="fetchTableData"
>
<a-tab-pane v-for="item in tabList" :key="item.key" :tab="item.label" />
</a-tabs>
<!-- 空状态 -->
<a-empty v-if="!loading && tabList.length === 0" description="暂无数据" />
<div class="body_zhengti">
<div class="echarts">
<a-spin :spinning="dataLoading">
<div v-if="pieData.length > 0" ref="chartRef" class="pie-chart"></div>
<a-empty
v-if="!dataLoading && pieData.length === 0"
description="暂无数据"
/>
</a-spin>
</div>
<div class="table">
<BasicTable
ref="tableRef"
:columns="columns"
:scrollY="380"
:list-url="
params.timeType == 'day'
? dayGetKendoListCust
: hourGetKendoListCust
"
:search-params="searchParams"
:transform-data="customTransform"
:enable-sort="true"
@sort-change="handleSortChange"
>
<template #ennm="{ column, record }">
<a-button type="link" size="small" @click="handleView(record)">{{
record.ennm
}}</a-button>
</template>
</BasicTable>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue';
import * as echarts from 'echarts';
import type { EChartsOption } from 'echarts';
import dayjs from 'dayjs';
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
import { dayGetKendoListCust, hourGetKendoListCust } from '@/api/stll';
import BasicTable from '@/components/BasicTable/index.vue';
import { useModelStore } from '@/store/modules/model';
const modelStore = useModelStore();
const props = defineProps<{
options?: any[];
typeKey?: string;
time?: string;
basicId?: string;
}>();
const JidiSelectEventStore = useJidiSelectEventStore();
const columns = [
{
key: 'ennm',
title: '电站名称',
dataIndex: 'ennm',
slots: { customRender: 'action' }
},
{
key: 'baseName',
title: '所属基地',
dataIndex: 'baseName'
},
{
key: 'addvcdName',
title: '行政区',
dataIndex: 'addvcdName'
},
{
key: 'hbrvcdName',
title: '所在河段',
dataIndex: 'hbrvcdName',
width: '400px'
},
{
key: 'qecRate',
title: `生态流量达标率(%)`,
dataIndex: 'qecRate',
sorter: true, //
width: '160px',
customRender: ({ text }: any) => {
if (text === null || text === undefined || text === '' || text === '-')
return '-';
return Number(text).toFixed(2);
}
}
];
const tableRef = ref();
//
const sortInfo = ref<{ field: string; order: string | null }>({
field: '',
order: null
});
const sort1 = ref([
{
field: 'baseStepSort',
dir: 'asc'
},
{
field: 'rvcdStepSort',
dir: 'asc'
},
{
field: 'siteStepSort',
dir: 'asc'
},
{
field: 'avqRate',
dir: 'desc'
}
]);
const sort2 = ref([
{
field: 'baseStepSort',
dir: 'asc'
},
{
field: 'rvcdStepSort',
dir: 'asc'
},
{
field: 'siteStepSort',
dir: 'asc'
}
]);
//
const searchParams = computed(() => {
let baseSort;
//
if (sortInfo.value.field && sortInfo.value.order) {
baseSort = [
{
field: sortInfo.value.field,
dir: sortInfo.value.order === 'ascend' ? 'asc' : 'desc'
}
];
} else {
// 使
baseSort = params.value.key ? sort1.value : sort2.value;
}
return {
sort: baseSort
};
});
//
const handleSortChange = (info: {
field: string;
order: 'ascend' | 'descend' | null;
}) => {
sortInfo.value.field = info.field || '';
sortInfo.value.order = info.order || null;
// DOM
nextTick(() => {
fetchTableData();
});
};
//
const initDateRange = () => {
const today = dayjs();
const lastMonthSameDay = today.subtract(1, 'month');
return [lastMonthSameDay, today];
};
const dateRange = ref(initDateRange());
const params = ref({
qid: props.basicId || 'all',
key: props.typeKey || '',
timeType: props.time || 'day',
sTime: '',
eTime: ''
});
// Tab
const tabList = ref<any[]>([]);
const ecoFlowType = ref<string>('');
const loading = ref<boolean>(false);
const timeTypeOptions = [
{ label: '逐时', value: 'hour' },
{ label: '日', value: 'day' }
];
const jidiOptions = computed(() => {
return [
...JidiSelectEventStore.jidiData.map((item: any) => ({
value: item.wbsCode,
label: item.wbsName
}))
];
});
const ruleTypeOptions = computed(() => {
return (
props.options?.map((el: any) => ({
label: el.name,
value: el.key
})) || []
);
});
const filterOption = (input: string, option: any) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};
// ==================== ====================
const chartRef = ref<HTMLDivElement | null>(null);
let chartInstance: echarts.ECharts | null = null;
const pieData = ref<any[]>([]); //
const dataLoading = ref<boolean>(false);
const pieCode = ref<string[]>([]); //
//
const themeecLists = [];
const jdColor = [
'#4b79ab',
'#78c300',
'#9556a4',
'#df91ab',
'#7399c6',
'#dbb629',
'#56c2e3',
'#f56a06',
'#cdba75',
'#76523b',
'#df75b6',
'#00a050',
'#f5a644',
'#4b79ab',
'#78c300',
'#9556a4',
'#df91ab',
'#7399c6',
'#dbb629',
'#56c2e3',
'#f56a06',
'#cdba75',
'#76523b',
'#df75b6',
'#00a050',
'#f5a644'
];
//
const fetchPieData = async () => {
if (!ecoFlowType.value || !params.value.sTime || !params.value.eTime) return;
dataLoading.value = true;
try {
const { sTime, eTime, qid, key, timeType } = params.value;
//
const filters = [
qid != 'all'
? {
field: 'baseId',
operator: 'eq',
dataType: 'string',
value: qid
}
: null,
{
field: 'dtin',
operator: 'eq',
dataType: 'string',
value: '1'
},
{
field: 'tm',
operator: 'gte',
dataType: 'date',
value: sTime
},
{
field: 'tm',
operator: 'lte',
dataType: 'date',
value: eTime
},
key
? {
field: key,
operator: 'eq',
dataType: 'string',
value: ecoFlowType.value
}
: null
].filter(Boolean);
// key
if (!key) {
filters.push(
{
field: 'qecInterval',
operator: 'eq',
dataType: 'string',
value: 'QEC_STLL_6_NOEQMN'
},
{
field: 'mwrInterval',
operator: 'eq',
dataType: 'string',
value: 'QEC_STLL_6_NOEQMN'
},
{
field: 'avqInterval',
operator: 'eq',
dataType: 'string',
value: 'QEC_STLL_6_NOEQMN'
}
);
}
let obj: any = {
filter: {
logic: 'and',
filters: filters
},
group: [
qid !== 'all' ? { dir: 'asc', field: 'rvcdStepSort' } : null,
qid === 'all' ? { dir: 'asc', field: 'baseStepSort' } : null,
{
dir: 'asc',
field: qid === 'all' ? 'baseId' : 'hbrvcd'
},
qid !== 'all'
? { dir: 'asc', field: 'hbrvcdName' }
: { dir: 'asc', field: 'baseName' }
].filter(Boolean),
groupResultFlat: true
};
// TODO: API
// const res = timeType == 'day'
// ? await shengTaiLiuLiang.STLLTabsDay(obj)
// : await shengTaiLiuLiang.STLLTabsHour(obj);
let res =
timeType == 'day'
? await dayGetKendoListCust(obj)
: await hourGetKendoListCust(obj);
if (res?.data?.data) {
const dataSource = res.data.data.map((el: any) => ({
id: qid === 'all' ? el.baseId : el.hbrvcd,
name: qid === 'all' ? el.baseName || el.key : el.hbrvcdName,
value: qid === 'all' ? el.count_baseId : el.count_hbrvcd,
key: qid === 'all' ? el.baseId : el.hbrvcd
}));
pieData.value = dataSource;
pieCode.value = []; //
// DOM
await nextTick();
initOrUpdateChart();
} else {
pieData.value = [];
}
} catch (error) {
console.error('获取饼图数据失败:', error);
pieData.value = [];
} finally {
dataLoading.value = false;
}
};
//
const initOrUpdateChart = () => {
if (!chartRef.value) return;
//
if (!chartInstance) {
chartInstance = echarts.init(chartRef.value);
//
chartInstance.on('legendselectchanged', handleLegendSelectChanged);
}
updateChart();
};
//
const updateChart = () => {
if (!chartInstance) return;
const total =
pieData.value.reduce((pre: number, cur: any) => pre + cur.value, 0) || 0;
//
const colors = pieData.value.map((item: any, index: number) => {
const matched = themeecLists.find((i: any) => i.name === item.name);
return matched?.color || jdColor[index % jdColor.length];
});
const option: EChartsOption = {
color: colors,
tooltip: {
trigger: 'item',
formatter: '{b}: {c} (座) ({d}%)'
},
legend: {
orient: 'vertical',
right: 20,
top: 80,
type: 'scroll',
textStyle: {
width: 100, //
overflow: 'truncate', //
ellipsis: '...' //
}
},
title: [
{
text: total.toString(),
left: '34%',
top: '44%',
textAlign: 'center',
textStyle: {
fontSize: 24,
fontWeight: 'bold',
color: '#333'
}
},
{
text: '电站总数量',
left: '34%',
top: '51%',
textAlign: 'center',
textStyle: {
fontSize: 14,
color: '#666'
}
},
{
text: '(座)',
left: '34%',
top: '55%',
textAlign: 'center',
textStyle: {
fontSize: 12,
color: '#999'
}
}
],
series: [
{
name: '电站总数量',
type: 'pie',
radius: ['31%', '40%'],
center: ['35%', '50%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: true,
formatter: function (params) {
const maxLen = 8; //
let name = params.name;
if (name.length > maxLen) {
return name.substring(0, maxLen) + '...';
}
return name;
}
},
emphasis: {
label: {
show: true,
fontSize: 14,
fontWeight: 'bold'
}
},
data: pieData.value
}
]
};
chartInstance.setOption(option, true);
};
//
const handleLegendSelectChanged = (params: any) => {
const selected = params.selected;
const trueRivers = Object.keys(selected).filter(key => selected[key]);
const allFalse = Object.values(selected).every(value => value === false);
const selectedKeys = pieData.value
.filter((item: any) => trueRivers.includes(item.name))
.map((item: any) => item.key);
pieCode.value = allFalse ? ['0'] : selectedKeys;
//
fetchTableData();
};
//
const customTransform = (res: any) => {
return {
records: res?.data?.data || [],
total: res?.data?.total || 0
};
};
// Tab
const fetchTabList = async () => {
if (!params.value.sTime || !params.value.eTime) return;
loading.value = true;
try {
const { sTime, eTime, qid, key, timeType } = params.value;
//
const filters = [
qid != 'all'
? {
field: 'baseId',
operator: 'eq',
dataType: 'string',
value: qid
}
: null,
{
field: 'dtin',
operator: 'eq',
dataType: 'string',
value: '1'
},
{
field: 'tm',
operator: 'gte',
dataType: 'date',
value: sTime
},
{
field: 'tm',
operator: 'lte',
dataType: 'date',
value: eTime
}
].filter(Boolean);
// key
if (!key) {
filters.push(
{
field: 'qecInterval',
operator: 'eq',
dataType: 'string',
value: 'QEC_STLL_6_NOEQMN'
},
{
field: 'mwrInterval',
operator: 'eq',
dataType: 'string',
value: 'QEC_STLL_6_NOEQMN'
},
{
field: 'avqInterval',
operator: 'eq',
dataType: 'string',
value: 'QEC_STLL_6_NOEQMN'
}
);
}
let obj: any = {
filter: {
logic: 'and',
filters: filters
},
group: key
? [
{
dir: 'asc',
field: key
}
]
: [
{
dir: 'asc',
field: 'baseStepSort'
},
{
dir: 'asc',
field: 'baseId'
},
{
dir: 'asc',
field: 'baseName'
}
]
};
// key groupResultFlat
if (!key) {
obj.groupResultFlat = true;
}
// TODO: API
let res =
timeType == 'day'
? await dayGetKendoListCust(obj)
: await hourGetKendoListCust(obj);
// const res = timeType == 'day'
// ? await shengTaiLiuLiang.STLLTabsDay(par, group) dayGetKendoListCust,hourGetKendoListCust
// : await shengTaiLiuLiang.STLLTabsHour(par, group);
// API
// const res = {
// data: [
// {
// type: 1,
// qecCnt: 14,
// qecTCnt: 50,
// code: 'QEC_STLL_1_DY95',
// desc: '_:>=95%',
// typeName: '',
// key: 'QEC_STLL_1_DY95',
// keyName: '',
// count: 14
// },
// {
// type: 2,
// qecCnt: 13,
// qecTCnt: 71,
// code: 'QEC_STLL_2_DY95',
// desc: '_:>=95%',
// typeName: '',
// key: 'QEC_STLL_2_DY95',
// keyName: '',
// count: 13
// }
// ]
// };
if (res?.data?.data?.length > 0) {
const resData = res.data.data;
if (key) {
// ""
tabList.value = resData
.map((el: any) => ({
...el,
value: el.key,
label: `${el.keyName || el.typeName}(${el.count || el.qecCnt}座)`
}))
.filter((el: any) => el.key !== 'QEC_STLL_6_NOEQMN');
// ecoFlowType
const found = resData.find(
(el: any) => el.items?.[0] === ecoFlowType.value
);
// 使
ecoFlowType.value = found ? ecoFlowType.value : resData[0]?.key;
} else {
// ""
tabList.value = [
{
key: 'QEC_STLL_6_NOEQMN',
value: 'QEC_STLL_6_NOEQMN',
label: `无生态流量要求(${resData?.length}座)`
}
];
ecoFlowType.value = 'QEC_STLL_6_NOEQMN';
}
//
fetchPieData();
//
fetchTableData();
} else {
tabList.value = [];
}
} catch (error) {
console.error('获取 Tab 列表失败:', error);
tabList.value = [];
} finally {
loading.value = false;
}
};
const handleView = (record: any) => {
modelStore.modalVisible = true;
modelStore.params.sttp = 'ENG';
modelStore.title = record.ennm;
modelStore.params.stcd = record.stcd;
modelStore.params.eqtp = record.eqtp;
modelStore.filterStll = params.value.key;
};
//table
const fetchTableData = async () => {
//
const { sTime, eTime, qid, key, timeType } = params.value;
const filters: any[] = [
qid != 'all'
? {
field: 'baseId',
operator: 'eq',
dataType: 'string',
value: qid
}
: null,
{
field: 'tm',
operator: 'gte',
dataType: 'date',
value: sTime
},
{
field: 'tm',
operator: 'lte',
dataType: 'date',
value: eTime
},
{
field: 'dtin',
operator: 'eq',
dataType: 'string',
value: '1'
},
key
? {
field: key,
operator: 'eq',
dataType: 'string',
value: ecoFlowType.value
}
: null
].filter(Boolean);
if (!key) {
filters.push(
{
field: 'qecInterval',
operator: 'eq',
dataType: 'string',
value: 'QEC_STLL_6_NOEQMN'
},
{
field: 'mwrInterval',
operator: 'eq',
dataType: 'string',
value: 'QEC_STLL_6_NOEQMN'
},
{
field: 'avqInterval',
operator: 'eq',
dataType: 'string',
value: 'QEC_STLL_6_NOEQMN'
}
);
}
//
if (pieCode.value.length > 0) {
if (qid === 'all') {
filters.push({
field: 'baseId',
operator: 'in',
dataType: 'string',
value: pieCode.value
});
} else {
filters.push({
field: 'hbrvcd',
operator: 'in',
dataType: 'string',
value: pieCode.value
});
}
}
const filter = {
logic: 'and',
filters
};
tableRef.value?.getList(filter);
};
// ecoFlowType
watch(ecoFlowType, () => {
fetchPieData();
});
const handleSearch = () => {
// params
if (dateRange.value && dateRange.value.length === 2) {
params.value.sTime = dateRange.value[0].format('YYYY-MM-DD 00:00:00');
params.value.eTime = dateRange.value[1].format('YYYY-MM-DD 23:59:59');
}
// Tab
fetchTabList();
};
onMounted(() => {
//
if (dateRange.value && dateRange.value.length === 2) {
params.value.sTime = dateRange.value[0].format('YYYY-MM-DD 00:00:00');
params.value.eTime = dateRange.value[1].format('YYYY-MM-DD 23:59:59');
fetchTabList();
}
//
window.addEventListener('resize', handleResize);
});
onUnmounted(() => {
//
if (chartInstance) {
chartInstance.dispose();
chartInstance = null;
}
window.removeEventListener('resize', handleResize);
});
//
const handleResize = () => {
chartInstance?.resize();
};
</script>
<style scoped lang="scss">
.stlldbqk-container {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
background-color: #ffffff;
box-sizing: border-box;
// padding: 16px;
}
.body_zhengti {
width: 100%;
display: flex;
justify-content: space-between;
flex: 1;
.echarts {
width: 35%;
height: 482px;
position: relative;
.pie-chart {
width: 100%;
height: 100%;
}
:deep(.ant-spin-nested-loading) {
width: 100%;
height: 100%;
}
:deep(.ant-spin-container) {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
}
.table {
width: 65%;
height: 482px;
}
}
</style>

View File

@ -1,109 +1,322 @@
<!-- SidePanelItem.vue -->
<template>
<div>
<SidePanelItem title="生态流量达标情况" :clickprompt="obj">
<SidePanelItem title="生态流量达标情况" :click-action="{ show: true }">
<!-- 使用插槽自定义点击提示的内容 -->
<template #click-action-content>
<div v-if="titleData.cnt" style="max-width: 300px; line-height: 1.6">
<p>
1统计电站范围接入过生态流量数据的电站
<span
style="color: #5989ad; cursor: pointer; "
@click.stop="handleStationClick()"
>
({{titleData.cnt}})
</span>
</p>
<p>2当来水不足时生态流量不小于入库流量判定为达标</p>
<p>395%座数表示统计电站范围内时段达标率大于等于95%的电站数量</p>
</div>
</template>
<div class="body_topOne">
<a-radio-group v-model:value="mode">
<a-radio-button value="top">逐时</a-radio-button>
<a-radio-button value="left"></a-radio-button>
<a-radio-group v-model:value="mode" @change="dataChage">
<a-radio-button value="hour">逐时</a-radio-button>
<a-radio-button value="day"></a-radio-button>
</a-radio-group>
<div class="title_text">95%座数/总座数</div>
</div>
<a-spin :spinning="spinning">
<div>
<div v-for="el in datalist">
<div :key='el.key'>
<div v-for="el in datalist" @click="handleBarClick(el)">
<div :key="el.key">
<div class="boy_one">
<div style="flex: 1; white-space: nowrap;margin-right: 5px;">{{ el.name }}</div>
<img style="flex: 1;" src="@/assets/components/fgx.svg" alt="">
<div style="flex: 1; white-space: nowrap; margin-right: 5px">
{{ el.name }}
</div>
<img style="flex: 1" src="@/assets/components/fgx.svg" alt="" />
</div>
<div class="body_zhu">
<div class="body_biao">
<div v-for="value in allArr">
<div :key="value" class="nei_body">
<div v-if="value < (el?.key == null ? 1 : el.qecTCnt == 0 ? 0 : el.qecCnt / el.qecTCnt) * 20"
class="little_body" :style="{ backgroundColor: el.color }"></div>
<div
v-if="
value <
(el?.key == null
? 1
: el.qecTCnt == 0
? 0
: el.qecCnt / el.qecTCnt) *
20
"
class="little_body"
:style="{ backgroundColor: el.color }"
></div>
</div>
</div>
</div>
<div class="body_text">
{{ el.qecCnt }}/{{ el.qecTCnt }}
</div>
<div class="body_text">{{ el.qecCnt }}/{{ el.qecTCnt }}</div>
</div>
</div>
</div>
</div>
</a-spin>
</SidePanelItem>
<!-- 自定义弹框 -->
<a-modal
v-model:open="modalVisible"
:title="'生态流量达标情况'"
width="1536px"
:footer="null"
>
<STLLXFFS
v-if="modalVisible"
:options="list"
:typeKey="selectedItem.key"
:time="mode"
:basicId="baseid"
/>
</a-modal>
<!-- 环保自动监测工作开展情况弹框 -->
<a-modal
v-model:open="huanbaoModalVisible"
:title="'环保自动监测工作开展情况'"
width="1536px"
:footer="null"
>
<ModalYkzhbzdjcgz v-if="huanbaoModalVisible" :baseId="baseid" :titleData = titleData />
</a-modal>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { ref, onMounted, watch } from 'vue';
import SidePanelItem from '@/components/SidePanelItem/index.vue';
import {
qgcetQgcStaticData,
evnmAutoMonitorGetKendoListCust
} from '@/api/stll';
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
import STLLXFFS from './TwoLayer/ShengTaiLiuLiangDaBQKTwoLayer.vue';
import ModalYkzhbzdjcgz from './TwoLayer/ModalYkzhbzdjcgz.vue';
import HuanbaoZDJCGZKZ from '@/modules/huanbaozdjcgzkzQK/index.vue';
// 便
defineOptions({
name: 'shengtaidabiaoMod'
});
const obj =
{
const JidiSelectEventStore = useJidiSelectEventStore();
const baseid = ref('');
const obj = {
show: true,
value: '1、统计电站范围接入过生态流量数据的电站,2、当来水不足时生态流量不小于入库流量判定为达标,3、“≥95%座数”表示统计电站范围内时段达标率大于等于95%的电站数量',
}
const mode = ref('top');
value:
'1、统计电站范围接入过生态流量数据的电站,2、当来水不足时生态流量不小于入库流量判定为达标,3、“≥95%座数”表示统计电站范围内时段达标率大于等于95%的电站数量'
};
const mode = ref('hour');
const dataArr: any = ref([
{
name: '生态环境部门要求',
qecCnt: '41', //
qecTCnt: '55', //
type: 1
type: 1,
key: 'qecInterval'
},
{
name: '水利部门要求',
qecCnt: '41', //
qecTCnt: '55', //
type: 2
type: 2,
key: 'mwrInterval'
}
])
const list: any = ref(
[
]);
const list: any = ref([
{ name: '生态环境部门要求', type: 1, color: '#77C300', key: 'qecInterval' },
{ name: '水利部门要求', type: 2, color: '#56C3E3', key: 'mwrInterval' },
{ name: '多年平均流量 10%', type: 3, color: '#F76B01', key: 'avqInterval' },
{ name: '无生态流量要求', type: 4, color: '#B4B4B4', key: null },
]
)
const datalist: any = ref([])
const allArr: any = ref(Array.from({ length: 20 }, (_, i) => i))
const spinning = ref(false)
{ name: '无生态流量要求', type: 4, color: '#B4B4B4', key: null }
]);
const datalist: any = ref([]);
const allArr: any = ref(Array.from({ length: 20 }, (_, i) => i));
const spinning = ref(false);
const modalVisible = ref(false);
const modalTitle = ref('');
const selectedItem = ref<any>(null);
const huanbaoModalVisible = ref(false);
//
const handleStationClick = () => {
huanbaoModalVisible.value = true;
};
//
const handleBarClick = (item: any) => {
selectedItem.value = item;
// modalTitle.value = `${item.name} - `;
modalVisible.value = true;
};
// type list dataArr
const setStyle = () => {
if (dataArr.value.length == 0) {
return false
return false;
}
dataArr.value.forEach((item: any) => {
// list type
const matched = list.value.find((listItem: any) => listItem.type === item.type)
const matched = list.value.find(
(listItem: any) => listItem.type === item.type
);
if (matched) {
// dataArr
datalist.value.push({
...matched,
...item,
})
...item
});
}
})
console.log(datalist.value)
}
});
console.log(datalist.value);
};
const dataChage = () => {
getData();
};
const getData = async () => {
// 00:00:00 23:59:59
const now = new Date();
const oneMonthAgo = new Date(now);
oneMonthAgo.setMonth(oneMonthAgo.getMonth() - 1);
// YYYY-MM-DD
const formatDate = (date: Date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
const startDate = `${formatDate(oneMonthAgo)} 00:00:00`;
const endDate = `${formatDate(now)} 23:59:59`;
let params = {
filter: {
logic: 'and',
filters: [
baseid.value != 'all'
? {
field: 'baseId',
operator: 'eq',
dataType: 'string',
value: baseid.value
}
: null,
{
field: 'dtin',
operator: 'eq',
dataType: 'string',
value: '1'
},
{
field: 'type',
operator: 'eq',
dataType: 'string',
value: mode.value
},
{
field: 'tm',
operator: 'gte',
dataType: 'date',
value: startDate
},
{
field: 'tm',
operator: 'lte',
dataType: 'date',
value: endDate
}
].filter(Boolean)
}
};
spinning.value = true;
try {
let res = await qgcetQgcStaticData(params);
// API
if (res.data && res.data.list) {
const apiList = res.data.list;
// debugger
// 使type: 1 type: 2
if (apiList && apiList.length > 0) {
dataArr.value = apiList.slice(0, 2).map((item: any) => ({
// name: item.typeName || item.desc,
qecCnt: item.qecCnt,
qecTCnt: item.qecTCnt,
type: item.type
}));
//
datalist.value = [];
setStyle();
} else {
//
dataArr.value = [];
datalist.value = [];
}
}
} catch (error) {
console.error('获取生态流量达标数据失败:', error);
} finally {
spinning.value = false;
}
};
watch(
() => JidiSelectEventStore.selectedItem,
newVal => {
if (newVal && newVal.wbsCode) {
baseid.value = newVal.wbsCode;
getData();
}
},
{ deep: true, immediate: true }
);
//
const titleData:any = ref({ cnt: 0 })
const getcont = async () => {
let params = {
"filter": {
"logic": "and",
"filters": [
{
"field": "showIds",
"operator": "in",
"value": [
"7"
]
}
]
}
}
let res = await evnmAutoMonitorGetKendoListCust(params);
// [
// {
// "cnt": 452,
// "orderInx": 7,
// "orderInxName": "",
// "sttpFullPath": "ENG",
// "sttpCode": "ENG",
// "sttpName": ""
// }
// ]
let list = res?.data?.data[0];
if (list) {
titleData.value = list
}
// debugger
};
//
onMounted(() => {
setStyle()
setStyle();
getcont()
});
</script>
@ -131,6 +344,7 @@ onMounted(() => {
align-items: center;
justify-content: space-between;
cursor: pointer;
transition: all 0.3s ease;
.body_biao {
width: 100%;
@ -151,7 +365,6 @@ onMounted(() => {
.little_body {
width: 100%;
height: 100%;
}
}
}

View File

@ -1,8 +1,26 @@
<template>
<div>
<SidePanelItem title="生态流量达标情况" :clickprompt="obj">
<SidePanelItem title="生态流量达标情况" :click-action="{ show: true }">
<!-- 使用插槽自定义点击提示的内容 -->
<!-- 1时间2026-05-11 2026-06-11
-->
<template #click-action-content>
<div v-if="titleData.cnt" style="max-width: 300px; line-height: 1.6">
<p>1时间{{ getdate().startDate1 }} {{ getdate().endDate1 }}</p>
<p>
2范围接入过生态流量数据的电站<span
style="color: #5989ad; cursor: pointer"
@click.stop="handleStationClick()"
>
({{ titleData.cnt }}) </span
>
</p>
<p>3达标判定按环评批复或报告中对生态流量限值有明确要求的评判</p>
</div>
</template>
<div class="body_topOne">
<a-radio-group v-model:value="mode">
<a-radio-group v-model:value="mode" @change="getEcharts()">
<a-radio-button value="top">按基地</a-radio-button>
<a-radio-button value="left">按调节性能</a-radio-button>
</a-radio-group>
@ -12,30 +30,70 @@
</a-spin>
</SidePanelItem>
</div>
<!-- 环保自动监测工作开展情况弹框 -->
<a-modal
v-model:open="huanbaoModalVisible"
:title="'环保自动监测工作开展情况'"
width="1536px"
:footer="null"
>
<ModalYkzhbzdjcgz v-if="huanbaoModalVisible" :titleData="titleData" />
</a-modal>
</template>
<script lang="ts" setup>
import { ref, onMounted, watch } from 'vue';
import SidePanelItem from '@/components/SidePanelItem/index.vue';
import * as echarts from 'echarts';
import { eqqecRateCount, evnmAutoMonitorGetKendoListCust } from '@/api/stll';
import ModalYkzhbzdjcgz from '../shengtaidabiaoMod/TwoLayer/ModalYkzhbzdjcgz.vue';
// 便
defineOptions({
name: 'shengtaidabiaoMod'
});
const obj =
{
const obj = {
show: true,
value: '1、统计电站范围接入过生态流量数据的电站2、当来水不足时生态流量不小于入库流量判定为达标3、"≥95% 座数"表示统计电站范围内时段达标率大于等于 95% 的电站数量',
}
value:
'1、统计电站范围接入过生态流量数据的电站2、当来水不足时生态流量不小于入库流量判定为达标3、"≥95% 座数"表示统计电站范围内时段达标率大于等于 95% 的电站数量'
};
const mode = ref('top');
const spinning = ref(false)
const spinning = ref(false);
const chartRef = ref<HTMLElement | null>(null);
let chartInstance: echarts.ECharts | null = null;
//
const chartData = ref<{
categories: string[];
currentData: number[];
lastYearData: number[];
}>({
categories: [],
currentData: [],
lastYearData: []
});
const huanbaoModalVisible = ref(false);
//
const handleStationClick = () => {
huanbaoModalVisible.value = true;
};
//
const baseData = {
categories: ['金沙江干流', '雅砻江干流', '大渡河干流', '乌江干流', '长江上游干流', '湘西', '黄河上游干流', '黄河中游干流', '南盘江 - 红水河', '东北', '澜沧江干流', '闽浙赣', '其他'],
categories: [
'金沙江干流',
'雅砻江干流',
'大渡河干流',
'乌江干流',
'长江上游干流',
'湘西',
'黄河上游干流',
'黄河中游干流',
'南盘江 - 红水河',
'东北',
'澜沧江干流',
'闽浙赣',
'其他'
],
currentData: [98, 100, 99.5, 99.8, 100, 98.5, 100, 100, 100, 97, 100, 93, 98],
lastYearData: [92, 100, 99, 100, 100, 98, 100, 100, 100, 100, 100, 88, 93]
};
@ -48,14 +106,22 @@ const performanceData = {
};
//
const loadData = () => {
const loadData = async () => {
spinning.value = true;
// DOM
try {
//
await getEcharts();
// DOM
setTimeout(() => {
initChart();
spinning.value = false;
}, 50);
} catch (error) {
console.error('数据加载失败:', error);
spinning.value = false;
}
};
//
@ -80,8 +146,8 @@ const initChart = () => {
chartInstance = echarts.init(chartRef.value);
// mode
const data = mode.value === 'top' ? baseData : performanceData;
// 使
const data = chartData.value;
const isHorizontal = mode.value === 'top';
const option = {
@ -90,24 +156,30 @@ const initChart = () => {
axisPointer: {
type: 'shadow'
},
formatter: function(params: any) {
formatter: function (params: any) {
let result = params[0].name + '<br/>';
params.forEach((param: any) => {
const percentage = param.value.toFixed(2) + '%';
result += param.marker + param.seriesName + '&nbsp;&nbsp;<b>' + percentage + '</b><br/>';
result +=
param.marker +
param.seriesName +
'&nbsp;&nbsp;<b>' +
percentage +
'</b><br/>';
});
return result;
}
},
legend: {
data: ['当前', '去年同期'],
data: ['当前', '去年同期']
},
grid: { left: 10, right: 10, bottom: 20, top: 40, containLabel: true },
dataZoom: [
{
type: 'inside',
[isHorizontal ? 'yAxisIndex' : 'xAxisIndex']: 0,
// (mode='top'): X
// (mode='left'): XY
[isHorizontal ? 'xAxisIndex' : 'xAxisIndex']: 0,
filterMode: 'empty',
zoomOnMouseWheel: true,
moveOnMouseMove: false,
@ -118,7 +190,8 @@ const initChart = () => {
maxValueSpan: isHorizontal ? 20 : 5
}
],
xAxis: isHorizontal ? {
xAxis: isHorizontal
? {
type: 'value',
min: 80,
max: 100,
@ -133,7 +206,8 @@ const initChart = () => {
color: '#666',
formatter: '{value}'
}
} : {
}
: {
type: 'category',
data: data.categories,
axisLabel: {
@ -159,7 +233,8 @@ const initChart = () => {
show: false
}
},
yAxis: isHorizontal ? {
yAxis: isHorizontal
? {
type: 'category',
data: data.categories,
inverse: true,
@ -185,7 +260,8 @@ const initChart = () => {
splitLine: {
show: false
}
} : {
}
: {
type: 'value',
min: 0,
max: 100,
@ -209,7 +285,7 @@ const initChart = () => {
itemStyle: {
color: '#5470C6'
},
barWidth: isHorizontal ? 8 : 8,
barWidth: isHorizontal ? 8 : 8
// barGap: '30%'
},
{
@ -219,7 +295,7 @@ const initChart = () => {
itemStyle: {
color: '#91CC75'
},
barWidth: isHorizontal ? 8: 8,
barWidth: isHorizontal ? 8 : 8
// barGap: '30%'
}
]
@ -232,11 +308,176 @@ const initChart = () => {
chartInstance?.resize();
}, 0);
};
const getdate = () => {
const now = new Date();
const oneMonthAgo = new Date(now);
oneMonthAgo.setMonth(oneMonthAgo.getMonth() - 1);
// YYYY-MM-DD
const formatDate = (date: Date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
const startDate = `${formatDate(oneMonthAgo)} 00:00:00`;
const endDate = `${formatDate(now)} 23:59:59`;
const startDate1 = `${formatDate(oneMonthAgo)}`;
const endDate1 = `${formatDate(now)}`;
return { startDate, endDate, startDate1, endDate1 };
};
const getEcharts = async () => {
let params = {
filter: {
logic: 'and',
filters: [
mode.value == 'top'
? {
field: 'dtinEnv',
operator: 'in',
dataType: 'string',
value: [1, 2]
}
: {
field: 'type',
operator: 'eq',
dataType: 'string',
value: 'DAY'
},
{
field: 'tm',
operator: 'gte',
dataType: 'date',
value: getdate().startDate
},
{
field: 'tm',
operator: 'lte',
dataType: 'date',
value: getdate().endDate
}
]
},
group:
mode.value == 'top'
? [
{
dir: 'asc',
field: 'basestepsort'
},
{
dir: 'asc',
field: 'baseId'
},
{
dir: 'asc',
field: 'baseName'
}
]
: [
{
dir: 'asc',
field: 'qecPerformance'
}
]
};
try {
const res: any = await eqqecRateCount(params);
//
if (res && res.success && res.data && res.data.data) {
const apiData = res.data.data;
// mode
if (mode.value === 'top') {
// baseId
const uniqueMap = new Map();
apiData.forEach((item: any) => {
if (!uniqueMap.has(item.baseId)) {
uniqueMap.set(item.baseId, item);
}
});
const uniqueData = Array.from(uniqueMap.values());
chartData.value = {
categories: uniqueData.map((item: any) => item.baseName || ''),
currentData: uniqueData.map((item: any) =>
item.qecRate != null ? Number(item.qecRate) : 0
),
lastYearData: uniqueData.map((item: any) =>
item.beforeQecRate != null ? Number(item.beforeQecRate) : 0
)
};
} else {
//
chartData.value = {
categories: apiData.map((item: any) => item.qecPerformanceName || ''),
currentData: apiData.map((item: any) =>
item.qecRate != null ? Number(item.qecRate) : 0
),
lastYearData: apiData.map((item: any) =>
item.beforeQecRate != null ? Number(item.beforeQecRate) : 0
)
};
}
} else {
console.warn('API 返回数据格式异常');
// 使
chartData.value = {
categories: [],
currentData: [],
lastYearData: []
};
}
} catch (error) {
console.error('API 调用失败:', error);
// 使
chartData.value = {
categories: [],
currentData: [],
lastYearData: []
};
}
};
//
const titleData: any = ref({ cnt: 0 });
const getcont = async () => {
let params = {
filter: {
logic: 'and',
filters: [
{
field: 'showIds',
operator: 'in',
value: ['7']
}
]
}
};
let res = await evnmAutoMonitorGetKendoListCust(params);
// [
// {
// "cnt": 452,
// "orderInx": 7,
// "orderInxName": "",
// "sttpFullPath": "ENG",
// "sttpCode": "ENG",
// "sttpName": ""
// }
// ]
let list = res?.data?.data[0];
if (list) {
titleData.value = list;
}
// debugger
};
//
onMounted(() => {
loadData();
getcont();
//
window.addEventListener('resize', () => {
chartInstance?.resize();
@ -270,7 +511,6 @@ watch(mode, () => {
.ant-radio-button-wrapper {
border: 2px solid #2f6b98 !important;
}
.ant-radio-button-wrapper-checked :before {

View File

@ -298,7 +298,7 @@ const handleExport = async () => {};
const handleViewDetail = (record: any) => {
modelStore.modalVisible = true;
modelStore.params.sttp = 'WT';
modelStore.title = record.stnm + '详情信息';
modelStore.title = record.stnm ;
modelStore.params.stcd = record.stcd;
};

View File

@ -910,7 +910,7 @@ function handleRowClick(record: any) {
stcd: record.stcd,
titleName: record.stnm
} as any // store
modelStore.title = record.stnm ? `${record.stnm} 详情信息` : '详情信息'
modelStore.title = record.stnm ? `${record.stnm} ` : ''
modelStore.tabList = handleTabs(modelStore.params)
modelStore.modalVisible = true

View File

@ -518,7 +518,7 @@ const handleViewDetail = (record: any) => {
if (record) {
modelStore.modalVisible = true;
modelStore.params.sttp = "WT";
modelStore.title = record.stnm + "详情信息";
modelStore.title = record.stnm ;
// modelStore.isBasicEdit = true;
if (tabIndex.value == "27") {
modelStore.params.enfc = "1";

View File

@ -38,8 +38,15 @@
</div>
<!-- 数据表格 -->
<a-table :columns="columns" :data-source="tableData" :loading="loading" :pagination="pagination"
:scroll="{ y: tableHeight }" row-key="stcd" @change="handleTableChange">
<a-table
:columns="columns"
:data-source="tableData"
:loading="loading"
:pagination="pagination"
:scroll="{ y: tableHeight }"
row-key="stcd"
@change="handleTableChange"
>
<template #bodyCell="{ column, record }">
<!-- 监测状态 -->
<template v-if="column.key === 'coenvwState'">
@ -65,23 +72,23 @@
</template>
<script lang="ts" setup>
import { ref, computed, watch, onMounted } from 'vue'
import { wbsbGetKendoList, getVmsstbprpt } from '@/api/sw'
import { vmsstbprptGetKendoList } from '@/api/sz'
import { useModelStore } from "@/store/modules/model";
import { ref, computed, watch, onMounted } from 'vue';
import { wbsbGetKendoList, getVmsstbprpt } from '@/api/sw';
import { vmsstbprptGetKendoList } from '@/api/sz';
import { useModelStore } from '@/store/modules/model';
const modelStore = useModelStore();
// ==================== Props ====================
const props = defineProps<{
baseId?: string
tabs?: any[]
activeKey?: string
}>()
baseId?: string;
tabs?: any[];
activeKey?: string;
}>();
// ==================== ====================
const tabIndex = ref(props.activeKey || '0')
const loading = ref(false)
const tableData = ref<any[]>([])
const tabIndex = ref(props.activeKey || '0');
const loading = ref(false);
const tableData = ref<any[]>([]);
const pagination = ref({
current: 1,
pageSize: 20,
@ -91,27 +98,27 @@ const pagination = ref({
showQuickJumper: true,
showTotal: (total: number) => `${total}`,
pageSizeOptions: ['10', '20', '50', '100']
})
const tableHeight = 'calc(48vh)'
});
const tableHeight = 'calc(48vh)';
//
const hydropowerStationList = ref<any[]>([])
const stationDataList: any = ref([])
const hydropowerStationList = ref<any[]>([]);
const stationDataList: any = ref([]);
// a-select options
const hydropowerStationOptions = computed(() => {
return hydropowerStationList.value.map(station => ({
label: station.wbsName,
value: station.wbsCode
}))
})
}));
});
const stationOptions = computed(() => {
return stationDataList.value.map(station => ({
label: station.stnm,
value: station.stcd
}))
})
}));
});
const searchData = ref<any>({
stcd: {
@ -120,58 +127,57 @@ const searchData = ref<any>({
dataDimensionData: props.baseId || 'all'
},
stnm: null
})
});
// ==================== ====================
const getRowSpanInfo = (dataIndex: string) => {
const spanMap = new Map()
const spanMap = new Map();
if (!tableData.value || tableData.value.length === 0) {
return spanMap
return spanMap;
}
let currentGroupStart = 0
let currentValue = tableData.value[0][dataIndex]
let currentGroupStart = 0;
let currentValue = tableData.value[0][dataIndex];
for (let i = 0; i < tableData.value.length; i++) {
const value = tableData.value[i][dataIndex]
const value = tableData.value[i][dataIndex];
if (value !== currentValue) {
//
spanMap.set(currentGroupStart, i - currentGroupStart)
currentGroupStart = i
currentValue = value
spanMap.set(currentGroupStart, i - currentGroupStart);
currentGroupStart = i;
currentValue = value;
}
}
//
spanMap.set(currentGroupStart, tableData.value.length - currentGroupStart)
spanMap.set(currentGroupStart, tableData.value.length - currentGroupStart);
return spanMap
}
return spanMap;
};
// ==================== Props ====================
// const baseId = ref('')
watch(
() => props.baseId,
(newVal) => {
newVal => {
if (newVal && newVal !== searchData.value.stcd.dataDimensionData) {
searchData.value.stcd.dataDimensionData = newVal
fetchData()
searchData.value.stcd.dataDimensionData = newVal;
fetchData();
}
}
)
);
watch(
() => props.activeKey,
(newVal) => {
newVal => {
if (newVal && newVal !== tabIndex.value) {
tabIndex.value = newVal
fetchData()
tabIndex.value = newVal;
fetchData();
}
}
)
);
// ==================== ====================
const columns = computed(() => {
@ -182,16 +188,16 @@ const columns = computed(() => {
key: 'baseName',
width: 150,
customCell: (record: any, index: number) => {
const spanMap = getRowSpanInfo('baseName')
const rowSpan = spanMap.get(index)
const spanMap = getRowSpanInfo('baseName');
const rowSpan = spanMap.get(index);
if (rowSpan === undefined) {
//
return { rowSpan: 0 }
return { rowSpan: 0 };
}
//
return { rowSpan }
return { rowSpan };
}
},
{
@ -232,22 +238,25 @@ const columns = computed(() => {
align: 'center' as const,
fixed: 'right' as const
}
]
];
return baseColumns.filter(Boolean)
})
return baseColumns.filter(Boolean);
});
// ==================== ====================
const buildSearchFilter = () => {
const filters: any[] = []
const filters: any[] = [];
// ID
if (searchData.value?.stcd?.dataDimensionData && searchData.value.stcd.dataDimensionData !== 'all') {
if (
searchData.value?.stcd?.dataDimensionData &&
searchData.value.stcd.dataDimensionData !== 'all'
) {
filters.push({
field: 'baseId',
operator: 'eq',
value: searchData.value.stcd.dataDimensionData
})
});
}
// ID
@ -256,7 +265,7 @@ const buildSearchFilter = () => {
field: 'rstcd',
operator: 'eq',
value: searchData.value.stcd.stcdId
})
});
}
//
@ -265,7 +274,7 @@ const buildSearchFilter = () => {
field: 'rstcd',
operator: 'eq',
value: searchData.value.stnm
})
});
}
// tabIndex
@ -275,14 +284,14 @@ const buildSearchFilter = () => {
operator: 'eq',
dataType: 'string',
value: 'WQFB'
})
});
} else {
filters.push({
field: 'sttpCode',
operator: 'eq',
dataType: 'string',
value: 'WQ'
})
});
}
// Tab - React
@ -301,8 +310,8 @@ const buildSearchFilter = () => {
dataType: 'string',
value: 0
}
)
break
);
break;
case '1': // -
filters.push(
{
@ -317,8 +326,8 @@ const buildSearchFilter = () => {
dataType: 'string',
value: 1
}
)
break
);
break;
case '2': //
filters.push(
{
@ -333,8 +342,8 @@ const buildSearchFilter = () => {
dataType: 'string',
value: 2
}
)
break
);
break;
case '3': //
filters.push(
{
@ -349,21 +358,23 @@ const buildSearchFilter = () => {
dataType: 'string',
value: 0
}
)
break
);
break;
}
return {
logic: 'and',
filters: filters.filter((f) => f.value !== undefined && f.value !== null && f.value !== '')
}
}
filters: filters.filter(
f => f.value !== undefined && f.value !== null && f.value !== ''
)
};
};
// ==================== API ====================
const fetchData = async () => {
loading.value = true
loading.value = true;
try {
const filter = buildSearchFilter()
const filter = buildSearchFilter();
const params = {
take: pagination.value.pageSize,
skip: pagination.value.current,
@ -388,176 +399,174 @@ const fetchData = async () => {
{ field: 'rstcdStepSort', dir: 'asc' },
{ field: 'siteStepSort', dir: 'asc' }
],
groupResultFlat:false
}
groupResultFlat: false
};
console.log('【请求参数】', params)
const res = await vmsstbprptGetKendoList(params)
console.log('【响应数据】', res)
console.log('【请求参数】', params);
const res = await vmsstbprptGetKendoList(params);
console.log('【响应数据】', res);
//
let total = res.data.total
let records = res?.data?.data || res?.data
let total = res.data.total;
let records = res?.data?.data || res?.data;
// if (Array.isArray(res?.data?.data)) {
// records = res.data.data
// total = res.data.data.length
// }
tableData.value = records || []
pagination.value.total = total
loading.value = false
tableData.value = records || [];
pagination.value.total = total;
loading.value = false;
} catch (error) {
console.error('获取水文监测数据失败:', error)
tableData.value = []
pagination.value.total = 0
console.error('获取水文监测数据失败:', error);
tableData.value = [];
pagination.value.total = 0;
} finally {
loading.value = false
loading.value = false;
}
}
};
const getselect = async () => {
try {
const params = {
"filter": {
"logic": "and",
"filters": [
filter: {
logic: 'and',
filters: [
{
"field": "wbsType",
"operator": "eq",
"dataType": "string",
"value": "PSB"
field: 'wbsType',
operator: 'eq',
dataType: 'string',
value: 'PSB'
},
{
"field": "treeLevel",
"operator": "eq",
"dataType": "string",
"value": "1"
field: 'treeLevel',
operator: 'eq',
dataType: 'string',
value: '1'
}
]
},
"sort": [
sort: [
{
"field": "orderIndex",
"dir": "asc"
field: 'orderIndex',
dir: 'asc'
}
]
}
};
const res = await wbsbGetKendoList(params)
console.log('【水电站列表】', res)
const res = await wbsbGetKendoList(params);
console.log('【水电站列表】', res);
//
if (res?.data?.data && Array.isArray(res.data.data)) {
hydropowerStationList.value = res.data.data
console.log('站点数据列表', stationDataList.value)
getselectTwo(searchData.value.stcd.dataDimensionData)
console.log('【水电站数量】', hydropowerStationList.value.length)
hydropowerStationList.value = res.data.data;
console.log('站点数据列表', stationDataList.value);
getselectTwo(searchData.value.stcd.dataDimensionData);
console.log('【水电站数量】', hydropowerStationList.value.length);
} else {
console.warn('【警告】未获取到有效的水电站数据')
hydropowerStationList.value = []
console.warn('【警告】未获取到有效的水电站数据');
hydropowerStationList.value = [];
}
} catch (error) {
console.error('【错误】获取水电站列表失败:', error)
hydropowerStationList.value = []
console.error('【错误】获取水电站列表失败:', error);
hydropowerStationList.value = [];
}
}
};
const getselectTwo = async (code: any) => {
console.log('站点数据列表')
console.log('站点数据列表');
// Tab
// const sttpCodeValue = tabIndex.value === '3' ? 'WQFB' : 'WQ'
const params = {
"filter": {
"logic": "and",
"filters": [
code != 'all' ? {
"field": "baseId",
"operator": "contains",
"dataType": "string",
"value": code
} : null,
filter: {
logic: 'and',
filters: [
code != 'all'
? {
field: 'baseId',
operator: 'contains',
dataType: 'string',
value: code
}
: null,
{
"field": "sttpCode",
"operator": "eq",
"dataType": "string",
"value": "ENG"
field: 'sttpCode',
operator: 'eq',
dataType: 'string',
value: 'ENG'
}
].filter(Boolean)
},
"sort": code !== 'all'
sort:
code !== 'all'
? [
{
"field": "baseId",
"dir": "asc"
field: 'baseId',
dir: 'asc'
},
{
"field": "rvcdStepSort",
"dir": "asc"
field: 'rvcdStepSort',
dir: 'asc'
},
{
"field": "rstcdStepSort",
"dir": "asc"
field: 'rstcdStepSort',
dir: 'asc'
},
{
"field": "siteStepSort",
"dir": "asc"
field: 'siteStepSort',
dir: 'asc'
}
]
: [
{
"field": "ttpwr",
"dir": "desc"
field: 'ttpwr',
dir: 'desc'
}
],
"select": [
"stcd",
"stnm"
]
}
const res = await getVmsstbprpt(params)
select: ['stcd', 'stnm']
};
const res = await getVmsstbprpt(params);
// console.log('', res)
console.log('站点数据列表', res?.data?.data)
stationDataList.value = res?.data?.data || res?.data
}
console.log('站点数据列表', res?.data?.data);
stationDataList.value = res?.data?.data || res?.data;
};
// ==================== ====================
const filterOption = (input: string, option: any) => {
// 使 options option { label, value }
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};
const handleHydropowerStationChange = (value: string) => {
console.log('【水电站选择变化】', value)
console.log('【水电站选择变化】', value);
//
searchData.value.stnm = null
searchData.value.stcd.stcdId = ''
searchData.value.stnm = null;
searchData.value.stcd.stcdId = '';
//
getselectTwo(value)
getselectTwo(value);
//
// pagination.value.current = 1
// fetchData()
}
};
const handleStationChange = (value: string | undefined) => {
console.log('【测站选择变化】', value)
console.log('【测站选择变化】', value);
// ID
if (value) {
searchData.value.stcd.stcdId = value
searchData.value.stcd.stcdId = value;
} else {
searchData.value.stcd.stcdId = ''
searchData.value.stcd.stcdId = '';
}
}
};
const handleSearch = () => {
console.log('【搜索】', searchData.value)
pagination.value.current = 1
fetchData()
}
console.log('【搜索】', searchData.value);
pagination.value.current = 1;
fetchData();
};
const handleReset = () => {
console.log('【重置】')
console.log('【重置】');
searchData.value = {
stcd: {
dataDimensionType: 'hyBase',
@ -565,45 +574,46 @@ const handleReset = () => {
dataDimensionData: props.baseId || 'all'
},
stnm: null
}
pagination.value.current = 1
fetchData()
}
};
pagination.value.current = 1;
fetchData();
};
const handleTabChange = (key: string) => {
console.log('【Tab切换】', key)
tabIndex.value = key
pagination.value.current = 1
fetchData()
}
console.log('【Tab切换】', key);
tabIndex.value = key;
pagination.value.current = 1;
fetchData();
};
const handleTableChange = (pag: any) => {
pagination.value.current = pag.current
pagination.value.pageSize = pag.pageSize
fetchData()
}
pagination.value.current = pag.current;
pagination.value.pageSize = pag.pageSize;
fetchData();
};
const handleViewDetail = (record: any) => {
if (record) {
modelStore.modalVisible = true;
modelStore.params.sttp = "WQFB";
modelStore.title = record.stnm + "详情信息";
// modelStore.isBasicEdit = true;
modelStore.params.sttp = 'WQ';
modelStore.title = record.stnm;
modelStore.params.stcd = record.stcd;
modelStore.modalVisible = true;
modelStore.params.sttpCode = record.sttpCode;
if(tabIndex.value == '3'){
modelStore.params.dtinType = '2'
}
}
// TODO:
}
};
// ==================== ====================
onMounted(() => {
console.log('【组件挂载】水文监测工作二级页面已加载')
fetchData()
getselect()
})
console.log('【组件挂载】水文监测工作二级页面已加载');
fetchData();
getselect();
});
</script>
<style scoped lang="scss">

View File

@ -724,7 +724,7 @@ const handleDataPointClick = (params: any) => {
if (stationData && stationData.stcd) {
modelStore.modalVisible = true;
modelStore.params.sttp = "WQFB";
modelStore.title = stationData.stnm + "详情信息";
modelStore.title = stationData.stnm ;
// modelStore.isBasicEdit = true;
modelStore.params.stcd = stationData.stcd;
}

View File

@ -249,8 +249,7 @@ const initChart = () => {
console.log('temperature:', params.data.value);
modelStore.modalVisible = true;
modelStore.params.sttp = "WT";
modelStore.title = params.data.stnm + "详情信息";
// modelStore.isBasicEdit = true;
modelStore.title = params.data.stnm;
modelStore.params.stcd = params.data.stcd;
modelStore.params.date = paramsOne.tm;
}

View File

@ -10,6 +10,17 @@ export const useModelStore = defineStore('model', () => {
const isBasicEdit = ref(false);
const showStcdSelector = ref(false); // 是否显示下拉框
const stcdOptions = ref<Array<{ label: string, value: string }>>([]); // 可选测站列表
// 新增:功能迁移所需的状态字段
const baseId = ref<string>(''); // 当前基地 ID
const hasPowerStatData = ref<boolean>(false); // 电站是否有专题数据
const isPowerStatPage = ref<boolean>(false); // 是否在电站专题页面
const verticalWaterStcd = ref<string>(''); // 垂向水温子站点编码
const aiSites = ref<any[]>([]); // AI 识别站点列表
const wtConfig = ref<{ ioWtrv?: boolean; hasRstcdWtvt?: boolean }>({}); // 水温配置
const wqShow = ref<boolean>(false); // 水质 AI 预测显示
const fishTabInfo = ref<any>(null); // 鱼类监测数据信息
const params = ref<{
sttp: string;
stcd: any;
@ -17,13 +28,23 @@ export const useModelStore = defineStore('model', () => {
show: any;
enfc:any;
eqtp:any;
baseId?: string; // 新增:基地 ID
sttpCode?: string; // 新增:站点类型代码
sttpMap?: string; // 新增:站点类型映射
dtinType?: string;
bldstt: string;
}>({
sttp: 'eng',
stcd: '',
date: '',
show: true,
enfc:'0',
eqtp:''
eqtp:'',
baseId: '',
sttpCode: '',
sttpMap: '',
dtinType:'',
bldstt:'',
});
const filterStll= ref('')
return {
@ -36,5 +57,14 @@ export const useModelStore = defineStore('model', () => {
showStcdSelector, // 新增
stcdOptions, // 新增
filterStll,
// 新增返回字段
baseId,
hasPowerStatData,
isPowerStatPage,
verticalWaterStcd,
aiSites,
wtConfig,
wqShow,
fishTabInfo,
};
});

View File

@ -28,110 +28,110 @@ onMounted(() => {
const showMapModal = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "ENG";
modelStore.title = "三峡 详情信息";
modelStore.title = "三峡 ";
modelStore.isBasicEdit = true;
};
const showMapModal1 = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "WT";
modelStore.title = "水温 详情信息";
modelStore.title = "水温 ";
modelStore.isBasicEdit = true;
};
const showMapModal2 = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "WQFB";
modelStore.title = "水质 详情信息";
modelStore.title = "水质 ";
modelStore.isBasicEdit = true;
};
const showMapModal3 = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "FH";
modelStore.title = "栖息地 详情信息";
modelStore.title = "栖息地 ";
modelStore.isBasicEdit = true;
};//
const showMapModal4 = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "fh_zq_point";
modelStore.title = "栖息地流量 详情信息";
modelStore.title = "栖息地流量 ";
modelStore.isBasicEdit = true;
};
const showMapModal5 = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "fp_point";
modelStore.title = "过鱼设施 详情信息";
modelStore.title = "过鱼设施 ";
modelStore.isBasicEdit = true;
};
const showMapModal6 = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "FB";
modelStore.title = "鱼类增殖站 详情信息";
modelStore.title = "鱼类增殖站 ";
modelStore.isBasicEdit = true;
};
//
const showMapModal7 = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "VA";
modelStore.title = "动物救助站 详情信息";
modelStore.title = "动物救助站 ";
modelStore.isBasicEdit = true;
};
const showMapModal8 = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "VP";
modelStore.title = "珍稀植物园 详情信息";
modelStore.title = "珍稀植物园 ";
modelStore.isBasicEdit = true;
};
const showMapModal9 = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "WE";
modelStore.title = "水生生态调查断面 详情信息";
modelStore.title = "水生生态调查断面 ";
modelStore.isBasicEdit = true;
};
const showMapModal10 = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "WVA";
modelStore.title = "野生动物监测 详情信息";
modelStore.title = "野生动物监测 ";
modelStore.isBasicEdit = true;
};
const showMapModal11 = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "VD_FBFM";
modelStore.title = "AI视频监控站 详情信息";
modelStore.title = "AI视频监控站 ";
modelStore.isBasicEdit = true;
};
const showMapModal12 = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "eng_alarm_point";
modelStore.title = "水电站告警情况 详情信息";
modelStore.title = "水电站告警情况 ";
modelStore.isBasicEdit = true;
};
const showMapModal13 = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "FPRD";
modelStore.title = "鱼类调查装置 详情信息";
modelStore.title = "鱼类调查装置 ";
modelStore.isBasicEdit = true;
};
const showMapModal14 = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "DW_2";
modelStore.title = "低温水减缓设施-叠梁门 详情信息";
modelStore.title = "低温水减缓设施-叠梁门 ";
modelStore.isBasicEdit = true;
};
const showMapModal15 = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "DW_5";
modelStore.title = "前置挡墙 详情信息";
modelStore.title = "前置挡墙 ";
modelStore.isBasicEdit = true;
};
const showMapModal16 = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "DW_6";
modelStore.title = "隔水幕墙 详情信息";
modelStore.title = "隔水幕墙 ";
modelStore.isBasicEdit = true;
};
const showMapModal17 = () => {
modelStore.modalVisible = true;
modelStore.params.sttp = "DW_1";
modelStore.title = "夹岩双层取水 详情信息";
modelStore.title = "夹岩双层取水 ";
modelStore.isBasicEdit = true;
};
//DW_5