添加栖息地弹框,修改批复文件显示多个

This commit is contained in:
扈兆增 2026-06-10 15:45:16 +08:00
parent cc8c1e0647
commit 34502b7ed2
18 changed files with 7774 additions and 4450 deletions

View File

@ -1,6 +1,12 @@
import request from '@/utils/request'; import request from '@/utils/request';
import { AxiosPromise } from 'axios'; import { AxiosPromise } from 'axios';
import { LoginData, TokenResult, VerifyCode } from './types'; import { LoginData, TokenResult, VerifyCode } from './types';
export function getAccessToken() {
return request({
url: '/register/accessToken',
method: 'get'
});
}
/** /**
* *
@ -52,8 +58,11 @@ export function registerUser(data: any): AxiosPromise<any> {
*/ */
export function getBasinList(): AxiosPromise<any[]> { export function getBasinList(): AxiosPromise<any[]> {
return request({ return request({
url: '/env/rvcd/regDropdown', url: '/register/dropdown/rvcd',
method: 'get', method: 'get',
headers: {
'register-token': localStorage.getItem('register-token') || ''
}
// params: baseid ? { baseid } : {} // params: baseid ? { baseid } : {}
}); });
} }
@ -63,9 +72,12 @@ export function getBasinList(): AxiosPromise<any[]> {
*/ */
export function getGroupList(): AxiosPromise<any[]> { export function getGroupList(): AxiosPromise<any[]> {
return request({ return request({
url: '/env/hycd/regDropdown', url: '/register/dropdown/hycd',
method: 'get', method: 'get',
params:{lx:1} params: { lx: 1 },
headers: {
'register-token': localStorage.getItem('register-token') || ''
}
}); });
} }
@ -74,20 +86,26 @@ export function getGroupList(): AxiosPromise<any[]> {
*/ */
export function getCompanyList(): AxiosPromise<any[]> { export function getCompanyList(): AxiosPromise<any[]> {
return request({ return request({
url: '/env/hycd/regDropdown', url: '/register/dropdown/hycd',
method: 'get', method: 'get',
params: { lx:2 } params: { lx: 2 },
headers: {
'register-token': localStorage.getItem('register-token') || ''
}
}); });
} }
/** /**
* *
*/ */
export function getStationList(params:any): AxiosPromise<any[]> { export function getStationList(params: any): AxiosPromise<any[]> {
return request({ return request({
url: '/env/engInfo/regDropdown', url: '/register/dropdown/engInfo',
method: 'post', method: 'post',
data: params data: params,
headers: {
'register-token': localStorage.getItem('register-token') || ''
}
}); });
} }
@ -110,7 +128,11 @@ export function sendSmsCode(phone: string, type = 1): AxiosPromise<any> {
* @param code * @param code
* @param type 1- 2- * @param type 1- 2-
*/ */
export function verifySmsCode(phone: string, code: string, type = 1): AxiosPromise<any> { export function verifySmsCode(
phone: string,
code: string,
type = 1
): AxiosPromise<any> {
return request({ return request({
url: '/sms/verifyCode', url: '/sms/verifyCode',
method: 'post', method: 'post',
@ -123,7 +145,10 @@ export function verifySmsCode(phone: string, code: string, type = 1): AxiosPromi
* @param phone * @param phone
* @param code * @param code
*/ */
export function smsLoginApi(phone: string, code: string): AxiosPromise<TokenResult> { export function smsLoginApi(
phone: string,
code: string
): AxiosPromise<TokenResult> {
return request({ return request({
url: '/sms/login', url: '/sms/login',
method: 'post', method: 'post',
@ -137,7 +162,11 @@ export function smsLoginApi(phone: string, code: string): AxiosPromise<TokenResu
* @param code * @param code
* @param password * @param password
*/ */
export function resetPassword(phone: string, code: string, password: string): AxiosPromise<any> { export function resetPassword(
phone: string,
code: string,
password: string
): AxiosPromise<any> {
return request({ return request({
url: '/sms/resetPassword', url: '/sms/resetPassword',
method: 'post', method: 'post',

View File

@ -62,10 +62,33 @@ export function getMonitorData(data: any) {
data data
}); });
} }
// 监测数据 水温查询 栖息地
export function getMonitorDataWt(data: any) {
return request({
url: '/wt/msstbprpt/GetKendoList',
method: 'post',
data
});
}
export function getMonitorDataWq(data: any) {
return request({
url: '/wq/msstbprpt/GetKendoList',
method: 'post',
data
});
}
export function getMonitorDataZq(data: any) {
return request({
url: '/zq/msstbprpt/GetKendoList',
method: 'post',
data
});
}
// 监测数据 - 水温 // 监测数据 - 水温
export function getMonitorDataWaterTemp(data: any) { export function getMonitorDataWaterTemp(data: any) {
return request({ return request({
url: '/api/wmp-env-server/sw/alongDetail/qgc/GetKendoListCust', url: '/wt/alongDetail/qgc/GetKendoListCust',
method: 'post', method: 'post',
data data
}); });
@ -73,7 +96,7 @@ export function getMonitorDataWaterTemp(data: any) {
// 监测数据 - 水温 - 查询显示 综合/等温 // 监测数据 - 水温 - 查询显示 综合/等温
export function getMonitorDataWaterTempPowerStation(params: any) { export function getMonitorDataWaterTempPowerStation(params: any) {
return request({ return request({
url: '/api/wmp-env-server/sw/wtrv/getIoWtrvFlag', url: '/wt/wtrv/getIoWtrvFlag',
method: 'get', method: 'get',
params params
}); });
@ -81,7 +104,7 @@ export function getMonitorDataWaterTempPowerStation(params: any) {
// 监测数据 - 水温 - 、综合分析导出数据 // 监测数据 - 水温 - 、综合分析导出数据
export function exportMonitorDataWaterTempPowerStation(params: any) { export function exportMonitorDataWaterTempPowerStation(params: any) {
return request({ return request({
url: '/api/wmp-env-server/sw/alongDetail/qgc/GetKendoListCust', url: '/wt/alongDetail/qgc/GetKendoListCust',
method: 'post', method: 'post',
params, params,
responseType: 'blob' responseType: 'blob'
@ -91,32 +114,55 @@ export function exportMonitorDataWaterTempPowerStation(params: any) {
// 监测数据 - 水温 - 查询是否显示 等温水深 // 监测数据 - 水温 - 查询是否显示 等温水深
export function getMonitorDataWaterTempPowerStation2(params: any) { export function getMonitorDataWaterTempPowerStation2(params: any) {
return request({ return request({
url: '/api/wmp-env-server/sw/alongDetail/qgc/stcdCheck2', url: '/wt/alongDetail/qgc/stcdCheck2',
method: 'get', method: 'get',
params params
}); });
} }
// 监测数据 - 垂向水温 // 监测数据 - 垂向水温
export function getMonitorDataWaterTempVertical(data: any) { export function getMonitorDataWaterTempVertical(data: any) {
return request({ return request({
url: '/api/wmp-env-server/sw/cxDetail/GetKendoListCust', url: '/wt/cxDetail/GetKendoListCust',
method: 'post',
data
});
}
// 监测数据 - 水质 判断是否显示综合分析
export function getMonitorDataWaterQuality(data: any) {
return request({
url: '/wq/vmsstbprpt/GetKendoList',
method: 'post',
data
});
}
// 监测数据 - 水质 - 获取水质参数
export function getMonitorDataWaterQualityDetail(data: any) {
return request({
url: '/wq/stbprp/GetStbprpYsByStcd',
method: 'get',
params: data
});
}
// 监测数据 - 水质 - 获取水质数据
export function getMonitorDataWaterQualityList(data: any) {
return request({
url: '/wq/data/noAuth/GetKendoListCust',
method: 'post', method: 'post',
data data
}); });
} }
// 生态流量 - 限制范围查询 - 日 // 生态流量 - 限制范围查询 - 日
export function getEngLimitDay(data: any) { export function getMonitorDataWaterTempVerticalDay(data: any) {
return request({ return request({
url: '/eq/interval/qgc/day/GetKendoListCust', url: '/eq/data/day/GetKendoListCust',
method: 'post', method: 'post',
data data
}); });
} }
// 生态流量 - 限制范围查询 - 月 // 生态流量 - 限制范围查询 - 小时
export function getEngLimit(data: any) { export function getMonitorDataWaterTempVerticalHour(data: any) {
return request({ return request({
url: '/eq/interval/qgc/month/GetKendoListCust', url: '/eq/data/GetKendoListCust',
method: 'post', method: 'post',
data data
}); });

File diff suppressed because it is too large Load Diff

View File

@ -143,13 +143,29 @@ const loadApprovalData = () => {
loading.value = true; loading.value = true;
queryPostUrlList(props.url, params).then(res => { queryPostUrlList(props.url, params).then(res => {
const data = res.data?.data || []; const data = res.data?.data || [];
const fileArray = data.map((item: any) => ({ if (data[0].flid == null) {
id: item.flpath.split('?')[1] || '', const fileArray = data.map((item: any) => ({
name: item.approvalFileNo || item.approvalFileTitle, id: item.flpath.split('?')[1] || '',
url: item.flpath || '' name: item.approvalFileNo || item.approvalFileTitle,
})); url: item.flpath || ''
hasLoaded.value = true; }));
updateFileList(fileArray); hasLoaded.value = true;
updateFileList(fileArray);
} else {
getIdUrl({
id: data[0].flid
}).then(res1 => {
const data = res1?.data || {};
const fileArray = Object.keys(data).map(key => ({
id: key,
name: data[key].name,
url: data[key].fullpath
}));
loading.value = false;
hasLoaded.value = true;
updateFileList(fileArray);
});
}
}); });
}; };

View File

@ -39,7 +39,15 @@
</a-tooltip> </a-tooltip>
</div> </div>
<div class="col-right" v-if="item.visible"> <div class="col-right" v-if="item.visible">
<a-tooltip :title="!isEdit ? item.vlsr : ''"> <a-tooltip
:title="
!isEdit
? item.vlsr || String(item.value).length > 10
? item.value
: ''
: ''
"
>
<span v-if="!isEdit && item.filed != ''">{{ <span v-if="!isEdit && item.filed != ''">{{
item.value || '-' item.value || '-'
}}</span> }}</span>
@ -250,6 +258,10 @@ const columnsConfig = ref([
{ {
type: 'DW_1', type: 'DW_1',
columns: DwOnePointColumns columns: DwOnePointColumns
},
{
type: 'ZQ',
columns: FhZQPointColumns
} }
//DW_1 //DW_1

View File

@ -45,9 +45,15 @@
</div> </div>
<!-- 底部图表区 --> <!-- 底部图表区 -->
<div class="bottom-section"> <div class="bottom-section">
<a-spin :spinning="isChartLoading" tip="加载中..."> <a-spin v-show="hasData" :spinning="isChartLoading" tip="加载中...">
<div class="chart-wrapper" ref="chartRef"></div> <div class="chart-wrapper" ref="chartRef"></div>
</a-spin> </a-spin>
<a-empty
v-show="!hasData && !isChartLoading"
description="暂无数据"
class="empty-wrapper h-full flex items-center justify-center"
style="flex-direction: column"
/>
</div> </div>
</div> </div>
</template> </template>
@ -55,7 +61,10 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref, onMounted, computed, watch, onUnmounted, nextTick } from 'vue'; import { ref, onMounted, computed, watch, onUnmounted, nextTick } from 'vue';
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { getEngLimit, getEngLimitDay } from '@/api/mapModal'; import {
getMonitorDataWaterTempVerticalDay,
getMonitorDataWaterTempVerticalHour
} from '@/api/mapModal';
import { useModelStore } from '@/store/modules/model'; import { useModelStore } from '@/store/modules/model';
import { DateSetting } from '@/utils/enumeration'; import { DateSetting } from '@/utils/enumeration';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
@ -74,6 +83,7 @@ const props = defineProps({
}); });
const hasLoaded = ref<boolean>(false); // const hasLoaded = ref<boolean>(false); //
const isChartLoading = ref<boolean>(false); const isChartLoading = ref<boolean>(false);
const hasData = ref<boolean>(true); //
const unqualifiedCount = ref<number>(0); const unqualifiedCount = ref<number>(0);
const complianceRate = ref<string>(''); const complianceRate = ref<string>('');
const limitInfo = ref<string>(''); const limitInfo = ref<string>('');
@ -131,7 +141,7 @@ const fetchLimitInfo = async () => {
const stcd = modelStore.params.stcd; const stcd = modelStore.params.stcd;
const { startTime, endTime } = getDateRange(); const { startTime, endTime } = getDateRange();
const res = await getEngLimit({ const res = await getMonitorDataWaterTempVerticalHour({
filter: { filter: {
logic: 'and', logic: 'and',
filters: [ filters: [
@ -165,7 +175,7 @@ const fetchDayData = async () => {
const stcd = modelStore.params.stcd; const stcd = modelStore.params.stcd;
const { startTime, endTime } = getDateRange(); const { startTime, endTime } = getDateRange();
const res = await getEngLimitDay({ const res = await getMonitorDataWaterTempVerticalDay({
filter: { filter: {
logic: 'and', logic: 'and',
filters: [ filters: [
@ -206,27 +216,6 @@ const fetchDayData = async () => {
const chartRef = ref<HTMLDivElement | null>(null); const chartRef = ref<HTMLDivElement | null>(null);
let chartInstance: echarts.ECharts | null = null; let chartInstance: echarts.ECharts | null = null;
//
const getMockData = () => {
const now = dayjs();
const data: any[] = [];
const count = timeType.value === 'hour' ? 48 : 30; // 4830
for (let i = count - 1; i >= 0; i--) {
const tm =
timeType.value === 'hour'
? now.subtract(i, 'hour').format('YYYY-MM-DD HH:mm:ss')
: now.subtract(i, 'day').format('YYYY-MM-DD HH:mm:ss');
data.push({
tm,
qi: Math.round(Math.random() * 100 + 150), // 150-250
qec: Math.round(Math.random() * 50 + 100), // 100-150
qecLimit: 145, //
qecSameLastYear: Math.round(Math.random() * 60 + 90) // 90-150
});
}
return data;
};
// //
const updateChart = (data: any[]) => { const updateChart = (data: any[]) => {
if (!chartInstance) return; if (!chartInstance) return;
@ -241,18 +230,22 @@ const updateChart = (data: any[]) => {
(a, b) => new Date(a.tm).getTime() - new Date(b.tm).getTime() (a, b) => new Date(a.tm).getTime() - new Date(b.tm).getTime()
); );
const xAxisData = sorted.map(item => dayjs(item.tm).format('MM-DD HH:mm')); const xAxisData = sorted.map(item =>
dayjs(timeType.value === 'hour' ? item.tm : item.dt).format(
timeType.value === 'hour' ? 'YYYY-MM-DD HH:mm' : 'YYYY-MM-DD'
)
);
const qiData = sorted.map(item => item.qi); const qiData = sorted.map(item => item.qi);
const qecData = sorted.map(item => item.qec); const qecData = sorted.map(item => item.qec);
const qecLimitData = sorted.map(item => item.qecLimit); const qecLimitData = sorted.map(item => item.qecLimit);
const qecSameLastYearData = sorted.map(item => item.qecSameLastYear); const beforeQecData = sorted.map(item => item.beforeQec);
// Y // Y
const flowValues = [ const flowValues = [
...qiData, ...qiData,
...qecData, ...qecData,
...qecLimitData, ...qecLimitData,
...qecSameLastYearData ...beforeQecData
].filter(v => v !== null && v !== undefined); ].filter(v => v !== null && v !== undefined);
const flowMax = flowValues.length > 0 ? Math.max(...flowValues) : 200; const flowMax = flowValues.length > 0 ? Math.max(...flowValues) : 200;
const flowYMax = Math.ceil(flowMax * 1.1); const flowYMax = Math.ceil(flowMax * 1.1);
@ -267,9 +260,19 @@ const updateChart = (data: any[]) => {
formatter: (params: any) => { formatter: (params: any) => {
if (!params || params.length === 0) return ''; if (!params || params.length === 0) return '';
const dataIndex = params[0].dataIndex; const dataIndex = params[0].dataIndex;
const fullTime = sorted[dataIndex]?.tm console.log(sorted[dataIndex]);
? dayjs(sorted[dataIndex].tm).format('YYYY-MM-DD HH:mm:ss') const fullTime =
: ''; timeType.value === 'hour'
? sorted[dataIndex]?.tm
: sorted[dataIndex]?.dt
? dayjs(
timeType.value === 'hour'
? sorted[dataIndex].tm
: sorted[dataIndex].dt
).format(
timeType.value === 'hour' ? 'YYYY-MM-DD HH:mm' : 'YYYY-MM-DD'
)
: '';
let html = `<div style="font-size:16px;margin-bottom:8px;">${fullTime}</div>`; let html = `<div style="font-size:16px;margin-bottom:8px;">${fullTime}</div>`;
// //
const formatRules: Record< const formatRules: Record<
@ -369,7 +372,7 @@ const updateChart = (data: any[]) => {
{ {
name: '去年同期生态流量', name: '去年同期生态流量',
type: 'line', type: 'line',
data: qecSameLastYearData, data: beforeQecData,
smooth: true, smooth: true,
symbol: 'circle', symbol: 'circle',
symbolSize: 4, symbolSize: 4,
@ -405,7 +408,9 @@ const initChart = () => {
if (chartInstance) { if (chartInstance) {
chartInstance.dispose(); chartInstance.dispose();
} }
chartInstance = echarts.init(chartRef.value); nextTick(() => {
chartInstance = echarts.init(chartRef.value);
});
}; };
const handleResize = () => { const handleResize = () => {
@ -422,22 +427,45 @@ const destroyChart = () => {
window.removeEventListener('resize', handleResize); window.removeEventListener('resize', handleResize);
}; };
// //
const fetchChartData = async () => { const fetchChartData = async () => {
isChartLoading.value = true; isChartLoading.value = true;
try { try {
// TODO: const stcd = modelStore.params.stcd;
// const stcd = modelStore.params.stcd; const { startTime, endTime } = getDateRange();
// const { startTime, endTime } = getDateRange();
// const res = await getEngChartList({ ... });
// updateChart(res?.data?.data || []);
// 2 loading const apiFn =
await new Promise(resolve => setTimeout(resolve, 2000)); timeType.value === 'day'
? getMonitorDataWaterTempVerticalDay
: getMonitorDataWaterTempVerticalHour;
// 使 const res = await apiFn({
const mockData = getMockData(); filter: {
updateChart(mockData); logic: 'and',
filters: [
{ field: 'stcd', operator: 'eq', dataType: 'string', value: stcd },
{
field: 'tm',
operator: 'gte',
dataType: 'date',
value: startTime
},
{
field: 'tm',
operator: 'lte',
dataType: 'date',
value: endTime
}
]
},
sort: [{ field: 'tm', dir: 'asc' }]
});
const rawData = res?.data?.data || [];
hasData.value = rawData.length > 0;
if (hasData.value) {
updateChart(rawData);
}
hasLoaded.value = true; hasLoaded.value = true;
} catch (error) { } catch (error) {
console.error('获取图表数据失败:', error); console.error('获取图表数据失败:', error);
@ -448,6 +476,7 @@ const fetchChartData = async () => {
// //
const handleQuery = () => { const handleQuery = () => {
hasData.value = true;
fetchLimitInfo(); fetchLimitInfo();
fetchDayData(); fetchDayData();
fetchChartData(); fetchChartData();
@ -456,6 +485,8 @@ const handleQuery = () => {
// timeType // timeType
watch(timeType, () => { watch(timeType, () => {
dateRange.value = initDateRange(); dateRange.value = initDateRange();
hasData.value = true;
fetchChartData();
}); });
watch( watch(
@ -466,10 +497,8 @@ watch(
fetchDayData(); fetchDayData();
// //
nextTick(() => { nextTick(() => {
setTimeout(() => { initChart();
initChart(); fetchChartData();
fetchChartData();
}, 2000);
}); });
window.addEventListener('resize', handleResize); window.addEventListener('resize', handleResize);
} }
@ -477,7 +506,9 @@ watch(
{ immediate: true } { immediate: true }
); );
onMounted(() => {}); onMounted(() => {
window.addEventListener('resize', handleResize);
});
onUnmounted(() => { onUnmounted(() => {
destroyChart(); destroyChart();

View File

@ -0,0 +1,626 @@
<template>
<div class="flow-measure">
<a-tabs v-model:activeKey="activeTabKey">
<a-tab-pane v-for="tab in tabsList" :key="tab.key" :tab="tab.name" />
<template #rightExtra>
<div class="search-bar">
<a-range-picker
v-model:value="dateRange"
format="YYYY-MM-DD HH:mm"
:show-time="showTimeConfig"
:allowClear="false"
:presets="DateSetting.RangeButton.month1"
:disabled-date="disabledDate"
/>
<a-button type="primary" class="search-btn" @click="handleSearch">
查询
</a-button>
</div>
</template>
</a-tabs>
<a-spin :spinning="isLoading" tip="加载中...">
<div class="tab-content">
<div class="content-body">
<div class="chart-wrapper">
<div ref="chartRef" class="chart-container"></div>
<a-empty
v-if="!chartData || chartData.length === 0"
description="暂无数据"
class="chart-empty"
/>
</div>
<div class="table-wrapper">
<BasicTable
:scrollY="480"
:scrollX="tableScrollX"
:columns="tableColumns"
:data="tableData"
/>
</div>
</div>
</div>
</a-spin>
<!-- 视频播放弹窗 -->
<a-modal
v-model:open="videoModalVisible"
:title="videoModalTitle"
:width="800"
:footer="null"
>
<div class="video-container">
<video
v-if="currentVideoUrl"
:src="currentVideoUrl"
controls
autoplay
class="video-player"
/>
<a-empty v-else description="暂无视频" />
</div>
</a-modal>
</div>
</template>
<script lang="ts" setup>
import {
ref,
watch,
onBeforeUnmount,
onMounted,
nextTick,
h,
computed
} from 'vue';
import dayjs, { Dayjs } from 'dayjs';
import * as echarts from 'echarts';
import { queryPostUrlList } from '@/api/mapModal';
import { useModelStore } from '@/store/modules/model';
import BasicTable from '@/components/BasicTable/index.vue';
import { DateSetting } from '@/utils/enumeration';
const modelStore = useModelStore();
const props = defineProps({
isActive: { type: Boolean, default: false },
url: { type: String, default: '' },
code: { type: String, default: '' },
stcd: { type: String, default: '' }
});
const isQxdMode = computed(() => props.code === 'qxd.tabs.lcjs');
const hasLoaded = ref(false);
const isLoading = ref(false);
const tableData = ref<any[]>([]);
const chartData = ref<any[]>([]);
const chartRef = ref<HTMLElement>();
let chartInstance: echarts.ECharts | null = null;
//
const videoModalVisible = ref(false);
const videoModalTitle = ref('');
const currentVideoUrl = ref('');
const tabsList = [{ name: '流量监测', key: 'flowMeasure' }];
const activeTabKey = ref('flowMeasure');
//
const showTimeConfig = {
format: 'HH:mm',
hourStep: 1,
minuteStep: 5,
secondStep: 60
};
const disabledDate = (current: Dayjs) =>
current && current.isAfter(dayjs(), 'day');
const initDateRange = (): [Dayjs, Dayjs] => {
return [dayjs().subtract(7, 'day'), dayjs()];
};
const dateRange = ref<[Dayjs, Dayjs] | undefined>(initDateRange());
//
const tableColumns = [
{
title: '时间',
dataIndex: 'tm',
width: 180,
fixed: 'left',
customRender: ({ text }: any) =>
text ? dayjs(text).format('YYYY-MM-DD HH:mm:ss') : '-'
},
{
title: '水位(m)',
dataIndex: 'z',
width: 120,
customRender: ({ text }: any) =>
text !== undefined && text !== null ? Number(text).toFixed(2) : '-'
},
{
title: '流量(m³/s)',
dataIndex: 'q',
width: 130,
customRender: ({ text }: any) =>
text !== undefined && text !== null ? Number(text).toFixed(1) : '-'
},
{
title: '流速(m³/s)',
dataIndex: 'v',
width: 130,
customRender: ({ text }: any) =>
text !== undefined && text !== null ? Number(text).toFixed(2) : '-'
},
{
title: '水位视频',
dataIndex: 'rzVideoPath',
width: 120,
customRender: ({ record }: any) => {
if (!record.rzVideoPath) return '-';
return h(
'a-button',
{
type: 'link',
size: 'small',
onClick: () => playVideo(record.rzVideoPath, '水位视频')
},
'-'
);
}
},
{
title: '流速视频',
dataIndex: 'speedVideoPath',
width: 120,
customRender: ({ record }: any) => {
if (!record.speedVideoPath) return '-';
return h(
'a-button',
{
type: 'link',
size: 'small',
onClick: () => playVideo(record.speedVideoPath, '流速视频')
},
'-'
);
}
}
];
const tableScrollX = tableColumns.reduce((s, c) => s + (c.width || 100), 0);
//
const playVideo = (videoUrl: string, title: string) => {
currentVideoUrl.value = videoUrl;
videoModalTitle.value = title;
videoModalVisible.value = true;
};
//
const initChart = () => {
if (!chartRef.value) return;
if (chartInstance) chartInstance.dispose();
chartInstance = echarts.init(chartRef.value);
updateChart(chartData.value);
};
//
const updateChart = (data: any[]) => {
if (!chartInstance) return;
if (!data || data.length === 0) {
chartInstance.clear();
return;
}
const sorted = [...data].sort(
(a, b) => new Date(a.tm).getTime() - new Date(b.tm).getTime()
);
const xAxisData = sorted.map(item => {
const hm = dayjs(item.tm).format('HH:mm');
if (hm === '00:00') {
const date = dayjs(item.tm).format('MM-DD');
return `${hm}\n${date}`;
}
return hm;
});
const zData = sorted.map(item => item.z);
const qData = sorted.map(item => item.q);
const vData = sorted.map(item => item.v);
const waterValues = zData.filter(v => v !== null && v !== undefined);
const waterMin = waterValues.length > 0 ? Math.min(...waterValues) : 0;
const waterMax = waterValues.length > 0 ? Math.max(...waterValues) : 10;
const flowValues = [...qData, ...vData].filter(
v => v !== null && v !== undefined
);
const flowMin = flowValues.length > 0 ? Math.min(...flowValues) : 0;
const flowMax = flowValues.length > 0 ? Math.max(...flowValues) : 10;
const formatRules: Record<
string,
{ format: (v: number) => string; unit: string }
> = {
水位: { format: v => v.toFixed(2), unit: '(m)' },
流量: { format: v => String(Math.round(v)), unit: '(m³/s)' },
流速: { format: v => v.toFixed(2), unit: '(m³/s)' }
};
const option = {
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(50, 50, 50, 0.9)',
textStyle: { color: '#fff', fontSize: 12 },
axisPointer: { type: 'cross' },
formatter: (params: any) => {
if (!params || params.length === 0) return '';
const dataIndex = params[0].dataIndex;
const fullTime = sorted[dataIndex]?.tm
? dayjs(sorted[dataIndex].tm).format('YYYY-MM-DD HH:mm:ss')
: '';
let html = `<div style="font-size:16px;margin-bottom:8px;">${fullTime}</div>`;
params.forEach((param: any) => {
if (param.value == null) return;
const rule = Object.entries(formatRules).find(([key]) =>
param.seriesName.includes(key)
);
const displayValue = rule
? rule[1].format(Number(param.value))
: param.value;
const unit = rule ? rule[1].unit : '';
html += `
<div style="display:flex;align-items:center;justify-content:space-between;margin:4px 0;">
<span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:${param.color};margin-right:8px;"></span>
<span style="flex:1;font-size:14px;text-align:left;margin-right:6px;">${param.seriesName}: </span>
<span style="font-size:14px;min-width:60px;text-align:right;"><strong>${displayValue}</strong> ${unit}</span>
</div>
`;
});
return html;
}
},
legend: {
type: 'scroll',
top: 10,
data: ['水位', '流量', '流速'],
textStyle: { fontSize: 12 },
selected: {
水位: true,
流量: true,
流速: true
}
},
grid: {
left: 60,
right: 100,
top: 80,
bottom: 60
},
xAxis: {
type: 'category',
data: xAxisData,
axisLine: { lineStyle: { color: '#000000' } },
axisTick: { show: false },
axisLabel: { fontSize: 12 },
splitLine: {
show: true,
lineStyle: { color: '#bfbfbf', type: 'solid' }
}
},
yAxis: [
{
name: '水位(m)',
type: 'value',
position: 'left',
axisLine: { show: true, lineStyle: { color: '#56C2E3' } },
axisLabel: { color: '#56C2E3' },
nameTextStyle: { color: '#56C2E3' },
alignTicks: true,
scale: true,
splitNumber: 9
},
{
name: '流量(m³/s)',
type: 'value',
position: 'right',
axisLine: { show: true, lineStyle: { color: '#9556A4' } },
axisLabel: { color: '#9556A4' },
nameTextStyle: { color: '#9556A4' },
alignTicks: true,
scale: true,
splitNumber: 9
},
{
name: '流速(m³/s)',
type: 'value',
position: 'right',
axisLine: { show: true, lineStyle: { color: '#78C300' } },
axisLabel: { color: '#78C300' },
nameTextStyle: { color: '#78C300' },
alignTicks: true,
scale: true,
splitNumber: 9,
offset: 60
}
],
series: [
{
name: '水位',
type: 'line',
yAxisIndex: 0,
data: zData,
smooth: true,
symbol: 'circle',
symbolSize: 4,
lineStyle: { color: '#56C2E3', width: 2 },
itemStyle: { color: '#56C2E3' }
},
{
name: '流量',
type: 'line',
yAxisIndex: 1,
data: qData,
smooth: true,
symbol: 'circle',
symbolSize: 4,
lineStyle: { color: '#9556A4', width: 2 },
itemStyle: { color: '#9556A4' }
},
{
name: '流速',
type: 'line',
yAxisIndex: 2,
data: vData,
smooth: true,
symbol: 'circle',
symbolSize: 4,
lineStyle: { color: '#78C300', width: 2 },
itemStyle: { color: '#78C300' }
}
],
dataZoom: [
{
type: 'inside',
xAxisIndex: [0],
throttle: 50,
start: 0,
end: 100
}
],
toolbox: {
show: true,
feature: {
saveAsImage: { title: '保存为图片', type: 'png', pixelRatio: 2 }
},
right: 20,
top: 10
}
};
chartInstance.setOption(option, true);
};
//
const fetchData = async () => {
if (!dateRange.value) return;
// qxdstcd
if (isQxdMode.value && !props.stcd) {
return;
}
isLoading.value = true;
try {
// 使stcdqxd使props.stcd使modelStore.params.stcd
const currentStcd = isQxdMode.value ? props.stcd : modelStore.params.stcd;
const filterParams = {
filter: {
logic: 'and',
filters: [
{
field: 'stcd',
operator: 'eq',
dataType: 'string',
value: currentStcd
},
{
field: 'tm',
operator: 'gte',
dataType: 'date',
value: dateRange.value[0].format('YYYY-MM-DD HH:mm:ss')
},
{
field: 'tm',
operator: 'lte',
dataType: 'date',
value: dateRange.value[1].format('YYYY-MM-DD HH:mm:ss')
}
]
},
sort: [{ field: 'tm', dir: 'asc' }]
};
// qxd使getMonitorDataZqqxd使queryPostUrlList
let rawData;
if (isQxdMode.value) {
const { getMonitorDataZq } = await import('@/api/mapModal');
const res = await getMonitorDataZq(filterParams);
rawData = res?.data?.data || res?.data?.records || [];
} else {
const res = await queryPostUrlList(props.url, filterParams);
rawData = res?.data?.data || res?.data?.records || [];
}
tableData.value = [...rawData].reverse();
chartData.value = rawData;
nextTick(() => updateChart(rawData));
} catch (error) {
console.error('获取数据失败:', error);
tableData.value = [];
chartData.value = [];
if (chartInstance) chartInstance.clear();
} finally {
isLoading.value = false;
}
};
const handleSearch = () => fetchData();
const initData = () => {
if (hasLoaded.value) return;
nextTick(() => initChart());
fetchData();
hasLoaded.value = true;
};
watch(
() => props.isActive,
active => {
if (active && !hasLoaded.value) initData();
},
{ immediate: true }
);
watch(
() => modelStore.params.stcd,
(newStcd, oldStcd) => {
// qxdstorestcd
if (!isQxdMode.value && newStcd && newStcd !== oldStcd) fetchData();
}
);
// qxdprops.stcd
watch(
() => props.stcd,
(newStcd, oldStcd) => {
if (isQxdMode.value && newStcd && newStcd !== oldStcd) {
hasLoaded.value = false;
initData();
}
}
);
let resizeObserver: ResizeObserver | null = null;
watch(
() => props.isActive,
active => {
if (active && chartRef.value) {
setTimeout(() => {
if (chartInstance) chartInstance.resize();
}, 200);
if (!resizeObserver) {
resizeObserver = new ResizeObserver(() => {
if (chartInstance) chartInstance.resize();
});
resizeObserver.observe(chartRef.value);
}
}
}
);
const handleResize = () => {
if (chartInstance) chartInstance.resize();
};
onMounted(() => {
window.addEventListener('resize', handleResize);
});
onBeforeUnmount(() => {
if (chartInstance) {
chartInstance.dispose();
chartInstance = null;
}
window.removeEventListener('resize', handleResize);
if (resizeObserver) {
resizeObserver.disconnect();
resizeObserver = null;
}
});
</script>
<style lang="scss" scoped>
.flow-measure {
width: 100%;
min-height: 600px;
position: relative;
:deep(.ant-tabs-nav) {
margin-bottom: 4px;
}
.search-bar {
width: 100%;
margin-bottom: 12px;
display: flex;
align-items: center;
justify-content: flex-end;
.search-btn {
margin-left: 8px;
}
}
.tab-content {
width: 100%;
.content-body {
width: 100%;
display: flex;
height: 600px;
position: relative;
.chart-wrapper {
flex: 1;
height: 100%;
position: relative;
box-sizing: border-box;
padding-top: 10px;
.chart-container {
width: 100%;
height: 100%;
}
}
.chart-empty {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.table-wrapper {
flex: 1;
min-width: 500px;
height: 100%;
box-sizing: border-box;
padding: 10px;
overflow: hidden;
overflow-x: auto;
border-left: 1px solid #dcdfe6;
margin-left: 10px;
}
}
}
}
.video-container {
width: 100%;
min-height: 400px;
display: flex;
align-items: center;
justify-content: center;
.video-player {
width: 100%;
max-height: 600px;
border-radius: 4px;
}
}
</style>

View File

@ -321,7 +321,7 @@ const updateChart = (selectedRows: any[]) => {
fontSize: 12, fontSize: 12,
color: '#000000', color: '#000000',
formatter: function (value) { formatter: function (value) {
return value + '℃'; return value.toFixed(1) + '℃';
} }
}, },
splitLine: { show: true } splitLine: { show: true }
@ -349,6 +349,13 @@ const updateChart = (selectedRows: any[]) => {
}, },
right: 20, right: 20,
top: 10 top: 10
},
dataZoom: {
type: 'inside',
xAxisIndex: [0],
throttle: 50,
start: 0,
end: 100
} }
}; };

View File

@ -0,0 +1,778 @@
<template>
<div class="water-quality">
<a-tabs v-model:activeKey="activeTabKey">
<a-tab-pane v-for="tab in tabsList" :key="tab.key" :tab="tab.name" />
<template #rightExtra>
<div class="search-bar">
<a-range-picker
v-model:value="dateRange"
format="YYYY-MM-DD HH"
:show-time="showTimeConfig"
:allowClear="false"
:presets="DateSetting.RangeButton.hour"
:disabled-date="disabledDate"
/>
<a-button type="primary" class="search-btn" @click="handleSearch">
查询
</a-button>
<a-button
v-if="isSummaryMode"
class="search-btn"
@click="handleExport"
>
导出
</a-button>
</div>
</template>
</a-tabs>
<div class="tab-checkbox">
<a-checkbox-group
v-model:value="selectedColumns"
name="checkboxgroup"
:options="filteredCheckBoxOptions"
class="checkbox-group"
@change="handleCheckboxChange"
/>
</div>
<a-spin :spinning="isLoading" tip="加载中...">
<div class="tab-content">
<div class="content-body">
<div class="chart-wrapper">
<div ref="chartRef" class="chart-container"></div>
<a-empty
v-if="!chartData || chartData.length === 0"
description="暂无数据"
class="chart-empty"
/>
</div>
<div class="table-wrapper">
<BasicTable
:scrollY="480"
:scrollX="tableScrollX"
:columns="currentColumns"
:data="tableData"
/>
</div>
</div>
</div>
</a-spin>
</div>
</template>
<script lang="ts" setup>
import {
ref,
watch,
computed,
onMounted,
onBeforeUnmount,
nextTick
} from 'vue';
import dayjs, { Dayjs } from 'dayjs';
import * as echarts from 'echarts';
import {
getMonitorDataWaterQuality,
getMonitorDataWaterQualityDetail,
getMonitorDataWaterQualityList
} from '@/api/mapModal';
import { useModelStore } from '@/store/modules/model';
import BasicTable from '@/components/BasicTable/index.vue';
import { DateSetting } from '@/utils/enumeration';
const modelStore = useModelStore();
const props = defineProps({
isActive: { type: Boolean, default: false },
code: { type: String, default: '' },
stcd: { type: String, default: '' }
});
const isQxdMode = computed(() => props.code === 'qxd.tabs.szjc');
const hasLoaded = ref(false);
const isLoading = ref(false);
const tableData = ref<any[]>([]);
const chartData = ref<any[]>([]);
const chartRef = ref<HTMLElement>();
let chartInstance: echarts.ECharts | null = null;
const tabsList = [{ name: '水质', key: 'szjc.tabs.jcsj' }];
const activeTabKey = ref('szjc.tabs.jcsj');
//
const showTimeConfig = {
format: 'HH',
hourStep: 1,
minuteStep: 5,
secondStep: 60
};
const disabledDate = (current: Dayjs) =>
current && current.isAfter(dayjs(), 'day');
const initDateRange = (): [Dayjs, Dayjs] => {
const startDate = dayjs().subtract(7, 'day').startOf('day');
return [startDate, dayjs()];
};
const dateRange = ref<[Dayjs, Dayjs] | undefined>(initDateRange());
// ==================== Checkbox ====================
const selectedColumns = ref<any[]>([]);
const checkBoxOptions = [{ label: '综合分析', value: 'summary' }];
const showSummaryCheckbox = ref(false);
const isDataEmpty = computed(() => {
const data = Array.isArray(chartData.value) ? chartData.value : [];
return data.length === 0;
});
const filteredCheckBoxOptions = computed(() => {
if (isDataEmpty.value) return [];
const available = checkBoxOptions.filter(opt => {
if (opt.value === 'summary' && !showSummaryCheckbox.value) return false;
return true;
});
return available;
});
const isSummaryMode = computed(() => selectedColumns.value.includes('summary'));
const handleCheckboxChange = (values: any[]) => {
selectedColumns.value = values;
if (values.length === 0) {
selectedColumns.value = [];
}
fetchData();
};
// ==================== ====================
const qualityParams = ref<any[]>([]); // enable==1
const allDetailParams = ref<any[]>([]); //
const visibleSeriesNames = ref<string[]>([]); // series2
// showControlunit
const parseUnit = (showControl: string) => {
if (!showControl) return '';
try {
const config = JSON.parse(showControl);
return config.unit || '';
} catch {
return '';
}
};
// ==================== ====================
//
const fixedColumns = [
{
title: '时间',
dataIndex: 'tm',
fixed: 'left',
width: 160,
customRender: ({ text }: any) =>
text ? dayjs(text).format('YYYY-MM-DD HH:mm') : '-'
},
{
title: '水质要求',
dataIndex: 'wwqtgName',
fixed: 'left',
width: 100
},
{
title: '水质等级',
dataIndex: 'wqgrdName',
fixed: 'left',
width: 100
},
{
title: '是否达标',
dataIndex: 'sfdb',
fixed: 'left',
width: 100,
customRender: ({ text }: any) => {
const isUnqualified = text == 0; // 01
return {
props: {
style: { color: isUnqualified ? 'red' : 'inherit' }
},
children: text == 0 ? '不达标' : text == 1 ? '达标' : '-'
};
}
}
];
//
const fixedQualityColumns = computed(() => {
const columns = allDetailParams.value.map((p: any) => {
const unit = parseUnit(p.showControl);
const title = unit ? `${p.ysShowName}(${unit})` : p.ysShowName;
const dataIndex = p.ys.toLowerCase();
const isEnabled = p.enable == 1;
// 10051406160
const titleLen = title.length;
let width = 100;
if (titleLen > 6) {
width = 160;
} else if (titleLen > 5) {
width = 140;
}
const fieldUpper = p.ys.toUpperCase(); // max/min
return {
title,
dataIndex,
enabled: isEnabled,
width,
customRender: ({ text, record }: any) => {
if (!isEnabled) return '-'; // enable=0 -
if (text === undefined || text === null || text === '') return '-';
const num = Number(text);
if (isNaN(num)) return '-';
// max/minmax/min record
const maxList = record?.max;
const minList = record?.min;
let isOutOfRange = false;
if (Array.isArray(maxList) && maxList.length > 0) {
const maxItem = maxList.find((m: any) => m[fieldUpper] !== undefined);
if (maxItem && num > maxItem[fieldUpper]) {
isOutOfRange = true;
}
}
if (Array.isArray(minList) && minList.length > 0) {
const minItem = minList.find((m: any) => m[fieldUpper] !== undefined);
if (minItem && num < minItem[fieldUpper]) {
isOutOfRange = true;
}
}
return {
props: {
style: { color: isOutOfRange ? 'red' : 'inherit' }
},
children: num
};
}
};
});
//
if (isSummaryMode.value) {
columns.push({
title: '出库流量(m³/s)',
dataIndex: 'qo',
width: 140,
customRender: ({ text }: any) => {
if (text === undefined || text === null || text === '') return '-';
const num = Number(text);
return isNaN(num) ? '-' : num;
}
});
}
return columns;
});
const swjcColumns = computed(() => {
return [...fixedColumns, ...fixedQualityColumns.value];
});
const currentColumns = swjcColumns;
const tableScrollX = computed(() => {
const columns = currentColumns.value;
const totalWidth = columns.reduce(
(sum: number, col: any) => sum + (col.width || 120),
0
);
return totalWidth > 600 ? totalWidth : undefined;
});
// ==================== ====================
function shouldStagger(width: number, dataLen: number) {
return dataLen > Math.floor(width / 100);
}
function getAxisLabelConfig(chartWidth: number, xAxisData: string[]) {
const needStagger = shouldStagger(chartWidth, xAxisData.length);
return {
fontSize: 12,
interval: 'auto',
formatter: (value: string, index: number) => {
const [date, time] = value.split(' ');
if (needStagger) {
return index % 2 === 0 ? `${date}\n${time}\n ` : ` \n${date}\n${time}`;
}
return `${date}\n${time}`;
}
};
}
const updateChart = (data: any[], enabledParams: any[]) => {
if (!chartInstance) return;
if (!data || data.length === 0) {
chartInstance.clear();
return;
}
const sorted = [...data].sort(
(a, b) => new Date(a.tm).getTime() - new Date(b.tm).getTime()
);
const xAxisData = sorted.map(item =>
dayjs(item.tm).format('YYYY-MM-DD HH:mm')
);
const width = chartRef.value?.clientWidth || 0;
const axisLabelConfig = getAxisLabelConfig(width, xAxisData);
// series
const allSeries = enabledParams.map((param: any, index: number) => {
const showControl = param.showControl || '{}';
let lineColor = '';
let unit = '';
try {
const config = JSON.parse(showControl);
lineColor = config.lineColor || '';
unit = config.unit || '';
} catch {
// 使
}
console.log(param);
const dataIndex = param.ys.toLowerCase();
const legendName = param.ysShowName; // legendunit
const yAxisName = unit ? `${param.ysShowName}\n${unit}` : param.ysShowName; // Y+unit
const color = lineColor;
return {
name: legendName,
ysShowName: param.ysShowName,
unit,
yAxisName,
type: 'line',
data: sorted.map(item => item[dataIndex]),
smooth: true,
symbol: 'none',
lineStyle: { color: color, width: 2 },
itemStyle: { color: color }
};
});
// series
if (isSummaryMode.value) {
allSeries.push({
name: '出库流量',
ysShowName: '出库流量',
unit: 'm³/s',
yAxisName: '出库流量\nm³/s',
type: 'line',
data: sorted.map(item => item.qo),
smooth: true,
symbol: 'none',
lineStyle: { color: '#4B79AB', width: 2 },
itemStyle: { color: '#4B79AB' }
});
}
const legendData = allSeries.map((s: any) => s.name);
// series
if (visibleSeriesNames.value.length === 0) {
const defaultName = '溶解氧';
if (legendData.includes(defaultName)) {
visibleSeriesNames.value = [defaultName];
} else if (legendData.length > 0) {
visibleSeriesNames.value = [legendData[0]];
}
}
// series legend selected
const series = allSeries;
// Y visibleSeriesNames
const yAxisConfig: any[] = [];
const visibleSeriesList = series.filter((s: any) =>
visibleSeriesNames.value.includes(s.name)
);
console.log(visibleSeriesList[0]);
if (visibleSeriesList.length >= 1) {
yAxisConfig.push({
name: visibleSeriesList[0].yAxisName,
// nameLocation: 'middle',
// nameGap: 30,
type: 'value',
position: 'left',
// axisLine: { lineStyle: { color: visibleSeriesList[0].itemStyle.color } },
scale: true,
splitLine: {
show: true,
lineStyle: { color: '#bfbfbf', type: 'solid' }
}
});
// seriesyAxisIndex
series.forEach((s: any) => {
s.yAxisIndex = visibleSeriesNames.value.includes(s.name) ? 0 : 0;
});
}
if (visibleSeriesList.length >= 2) {
yAxisConfig.push({
name: visibleSeriesList[1].yAxisName,
// nameLocation: 'middle',
// nameGap: 35,
type: 'value',
position: 'right',
// axisLine: { lineStyle: { color: visibleSeriesList[1].itemStyle.color } },
scale: true,
splitLine: { show: false }
});
visibleSeriesList[0].yAxisIndex = 0;
visibleSeriesList[1].yAxisIndex = 1;
}
// legend selected
const legendSelected = legendData.reduce((acc: any, name) => {
acc[name] = visibleSeriesNames.value.includes(name);
return acc;
}, {});
const option: any = {
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(50,50,50,0.9)',
textStyle: { color: '#fff', fontSize: 12 },
axisPointer: { type: 'cross' },
formatter: (params: any) => {
if (!params?.length) return '';
const idx = params[0].dataIndex;
const fullTime = sorted[idx]?.tm
? dayjs(sorted[idx].tm).format('YYYY-MM-DD HH:mm')
: '';
let html = `<div style="font-size:16px;margin-bottom:8px;">${fullTime}</div>`;
params.forEach((p: any) => {
const v = p.value != null ? Number(p.value).toFixed(2) : '-';
html += `<div style="display:flex;align-items:center;justify-content:space-between;margin:4px 0;"><span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:${p.color};margin-right:8px;"></span><span style="flex:1;font-size:14px;">${p.seriesName}: </span><span style="font-size:14px;min-width:60px;text-align:right;"><strong>${v}</strong></span></div>`;
});
return html;
}
},
legend: {
type: 'scroll',
width: '80%',
right: 60,
top: 10,
data: legendData,
textStyle: { fontSize: 12 },
selected: legendSelected
},
grid: {
left: 60,
right: series.length >= 2 ? 60 : 40,
top: 80,
bottom: 80
},
xAxis: {
type: 'category',
data: xAxisData,
axisLine: { lineStyle: { color: '#000000' } },
axisTick: { show: false },
axisLabel: axisLabelConfig,
splitLine: {
show: true,
lineStyle: { color: '#bfbfbf', type: 'solid' }
}
},
yAxis: yAxisConfig.length === 1 ? yAxisConfig[0] : yAxisConfig,
series,
dataZoom: [
{ type: 'inside', xAxisIndex: [0], throttle: 50, start: 0, end: 100 }
],
toolbox: {
show: true,
feature: {
saveAsImage: { title: '保存为图片', type: 'png', pixelRatio: 2 }
},
right: 20,
top: 10
}
};
chartInstance.setOption(option, true);
};
// legend
const bindLegendEvent = () => {
if (!chartInstance) return;
chartInstance.off('legendselectchanged');
chartInstance.on('legendselectchanged', (params: any) => {
const selected = params.selected;
const name = params.name;
const wasSelected = selected[name]; // echarts already updated internal state
if (wasSelected) {
//
const prevVisible = [...visibleSeriesNames.value];
if (prevVisible.length >= 2) {
// 2
visibleSeriesNames.value = [prevVisible[1], name];
} else {
visibleSeriesNames.value = [...new Set([...prevVisible, name])];
}
} else {
//
visibleSeriesNames.value = visibleSeriesNames.value.filter(
n => n !== name
);
}
// 使allDetailParams
updateChart(chartData.value, allDetailParams.value);
});
};
// ==================== ====================
const fetchData = async () => {
if (!dateRange.value) return;
// qxdstcd
if (isQxdMode.value && !props.stcd) {
return;
}
isLoading.value = true;
try {
// 使stcdqxd使props.stcd使modelStore.params.stcd
const currentStcd = isQxdMode.value ? props.stcd : modelStore.params.stcd;
const filterParams = {
filter: {
logic: 'and',
filters: [
{
field: 'stcd',
operator: 'eq',
dataType: 'string',
value: currentStcd
},
{
field: 'tm',
operator: 'gte',
dataType: 'date',
value: dateRange.value[0].format('YYYY-MM-DD HH:mm:ss')
},
{
field: 'tm',
operator: 'lte',
dataType: 'date',
value: dateRange.value[1].format('YYYY-MM-DD HH:mm:ss')
}
]
},
sort: [{ field: 'tm', dir: 'asc' }]
};
//
const [qualityRes, detailRes, listRes] = await Promise.all([
getMonitorDataWaterQuality(filterParams),
getMonitorDataWaterQualityDetail({
stcd: currentStcd,
tbCode: 'WQ_R',
startTime: dateRange.value[0].format('YYYY-MM-DD HH:mm:ss'),
endTime: dateRange.value[1].format('YYYY-MM-DD HH:mm:ss')
}),
getMonitorDataWaterQualityList(filterParams)
]);
// datanull
const qualityData = qualityRes?.data?.data || qualityRes?.data?.records;
showSummaryCheckbox.value = !!qualityData && qualityData.length > 0;
// detail
const detailData = detailRes?.data?.data || detailRes?.data || [];
allDetailParams.value = detailData; //
qualityParams.value = detailData.filter((item: any) => item.enable == 1); // enable==1
// series
visibleSeriesNames.value = [];
//
const listData = listRes?.data?.data || listRes?.data?.records || [];
tableData.value = [...listData].reverse();
chartData.value = listData;
nextTick(() => updateChart(listData, allDetailParams.value));
} catch (error) {
console.error('获取水质数据失败:', error);
tableData.value = [];
chartData.value = [];
qualityParams.value = [];
if (chartInstance) chartInstance.clear();
} finally {
isLoading.value = false;
}
};
const handleSearch = () => fetchData();
const handleExport = () => {
/* 导出逻辑 */
};
const initData = () => {
if (hasLoaded.value) return;
nextTick(() => {
if (chartRef.value && !chartInstance)
chartInstance = echarts.init(chartRef.value);
// chart
nextTick(() => {
bindLegendEvent();
});
});
fetchData();
hasLoaded.value = true;
};
watch(
() => props.isActive,
active => {
if (active && !hasLoaded.value) initData();
},
{ immediate: true }
);
watch(
() => modelStore.params.stcd,
(newStcd, oldStcd) => {
// qxdstorestcd
if (!isQxdMode.value && newStcd && newStcd !== oldStcd) fetchData();
}
);
// qxdprops.stcd
watch(
() => props.stcd,
(newStcd, oldStcd) => {
if (isQxdMode.value && newStcd && newStcd !== oldStcd) {
hasLoaded.value = false;
initData();
}
}
);
// ResizeObserver
let resizeObserver: ResizeObserver | null = null;
watch(
() => props.isActive,
active => {
if (active && chartRef.value) {
setTimeout(() => {
if (chartInstance) chartInstance.resize();
}, 200);
if (!resizeObserver) {
resizeObserver = new ResizeObserver(() => {
if (chartInstance) chartInstance.resize();
});
resizeObserver.observe(chartRef.value);
}
}
}
);
const handleResize = () => {
if (chartInstance) chartInstance.resize();
};
onMounted(() => {
window.addEventListener('resize', handleResize);
});
onBeforeUnmount(() => {
if (chartInstance) {
chartInstance.dispose();
chartInstance = null;
}
window.removeEventListener('resize', handleResize);
if (resizeObserver) {
resizeObserver.disconnect();
resizeObserver = null;
}
});
</script>
<style lang="scss" scoped>
.water-quality {
width: 100%;
min-height: 600px;
position: relative;
:deep(.ant-tabs-nav) {
margin-bottom: 4px;
}
.search-bar {
width: 100%;
margin-bottom: 12px;
display: flex;
align-items: center;
justify-content: flex-end;
.search-btn {
margin-left: 8px;
}
}
.tab-checkbox {
position: absolute;
top: 12px;
left: 30%;
z-index: 100;
}
.tab-content {
width: 100%;
.content-body {
width: 100%;
display: flex;
height: 600px;
position: relative;
.chart-wrapper {
flex: 1;
height: 100%;
position: relative;
box-sizing: border-box;
padding-top: 10px;
.chart-container {
width: 100%;
height: 100%;
}
}
.chart-empty {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.table-wrapper {
flex: 1;
min-width: 500px;
height: 100%;
box-sizing: border-box;
padding: 10px;
overflow: hidden;
overflow-x: auto;
border-left: 1px solid #dcdfe6;
margin-left: 10px;
}
}
}
}
</style>

View File

@ -26,7 +26,7 @@
</template> </template>
</a-tabs> </a-tabs>
<div class="tab-checkbox" v-if="activeTabKey === 'swjc.tabs.jcsj'"> <div class="tab-checkbox">
<a-checkbox-group <a-checkbox-group
v-model:value="selectedColumns" v-model:value="selectedColumns"
name="checkboxgroup" name="checkboxgroup"
@ -105,6 +105,7 @@ import dayjs, { Dayjs } from 'dayjs';
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { Tooltip } from 'ant-design-vue'; import { Tooltip } from 'ant-design-vue';
import { import {
// getMonitorDataWaterTempList,
getMonitorDataWaterTemp, getMonitorDataWaterTemp,
getMonitorDataWaterTempPowerStation, getMonitorDataWaterTempPowerStation,
getMonitorDataWaterTempPowerStation2 getMonitorDataWaterTempPowerStation2
@ -117,7 +118,9 @@ import { InfoCircleOutlined } from '@ant-design/icons-vue';
const modelStore = useModelStore(); const modelStore = useModelStore();
const props = defineProps({ const props = defineProps({
isActive: { type: Boolean, default: false } code: { type: String, default: '' },
isActive: { type: Boolean, default: false },
stcd: { type: String, default: '' }
}); });
const hasLoaded = ref(false); const hasLoaded = ref(false);
@ -503,6 +506,7 @@ const updateChart = (data: any[]) => {
} }
}, },
legend: { legend: {
width: '80%',
type: 'scroll', type: 'scroll',
top: 10, top: 10,
data: ['水温'], data: ['水温'],
@ -685,6 +689,8 @@ const updateChart = (data: any[]) => {
}, },
legend: { legend: {
type: 'scroll', type: 'scroll',
width: '80%',
right: 60,
top: 10, top: 10,
data: [ data: [
'出库水温', '出库水温',
@ -809,10 +815,21 @@ const updateChart = (data: any[]) => {
}; };
// ==================== ==================== // ==================== ====================
const isQxdMode = computed(() => props.code === 'qxd.tabs.jcsj');
const fetchData = async () => { const fetchData = async () => {
if (!dateRange.value) return; if (!dateRange.value) return;
// qxdstcd
if (isQxdMode.value && !props.stcd) {
return;
}
isLoading.value = true; isLoading.value = true;
try { try {
// 使stcdqxd使props.stcd使modelStore.params.stcd
const currentStcd = isQxdMode.value ? props.stcd : modelStore.params.stcd;
const filterParams = { const filterParams = {
filter: { filter: {
logic: 'and', logic: 'and',
@ -821,7 +838,7 @@ const fetchData = async () => {
field: 'stcd', field: 'stcd',
operator: 'eq', operator: 'eq',
dataType: 'string', dataType: 'string',
value: modelStore.params.stcd value: currentStcd
}, },
{ {
field: 'tm', field: 'tm',
@ -840,22 +857,35 @@ const fetchData = async () => {
sort: [{ field: 'tm', dir: 'asc' }] sort: [{ field: 'tm', dir: 'asc' }]
}; };
const [mainRes, powerStationRes, powerStationRes2] = await Promise.all([ // qxdgetMonitorDataWaterTemp
getMonitorDataWaterTemp(filterParams), if (isQxdMode.value) {
getMonitorDataWaterTempPowerStation({ stcd: modelStore.params.stcd }), const mainRes = await getMonitorDataWaterTemp(filterParams);
getMonitorDataWaterTempPowerStation2({ stcd: modelStore.params.stcd }) const mainData = mainRes?.data?.data || mainRes?.data?.records || [];
]); showSummaryCheckbox.value = false;
showDeepCheckbox.value = false;
selectedColumns.value = [];
tableData.value = [...mainData].reverse();
chartData.value = mainData;
nextTick(() => updateChart(mainData));
} else {
//
const [mainRes, powerStationRes, powerStationRes2] = await Promise.all([
getMonitorDataWaterTemp(filterParams),
getMonitorDataWaterTempPowerStation({ stcd: currentStcd }),
getMonitorDataWaterTempPowerStation2({ stcd: currentStcd })
]);
const mainData = mainRes?.data?.data || mainRes?.data?.records || []; const mainData = mainRes?.data?.data || mainRes?.data?.records || [];
showSummaryCheckbox.value = !!powerStationRes?.data?.ioWtrv; showSummaryCheckbox.value = !!powerStationRes?.data?.ioWtrv;
const powerStation2Data = const powerStation2Data =
powerStationRes2?.data?.data || powerStationRes2?.data || null; powerStationRes2?.data?.data || powerStationRes2?.data || null;
showDeepCheckbox.value = showDeepCheckbox.value =
!!powerStationRes?.data?.hasRstcdWtvt && powerStation2Data !== null; !!powerStationRes?.data?.hasRstcdWtvt && powerStation2Data !== null;
tableData.value = [...mainData].reverse(); tableData.value = [...mainData].reverse();
chartData.value = mainData; chartData.value = mainData;
nextTick(() => updateChart(mainData)); nextTick(() => updateChart(mainData));
}
} catch (error) { } catch (error) {
console.error('获取数据失败:', error); console.error('获取数据失败:', error);
tableData.value = []; tableData.value = [];
@ -892,7 +922,19 @@ watch(
watch( watch(
() => modelStore.params.stcd, () => modelStore.params.stcd,
(newStcd, oldStcd) => { (newStcd, oldStcd) => {
if (newStcd && newStcd !== oldStcd) fetchData(); // qxdstorestcd
if (!isQxdMode.value && newStcd && newStcd !== oldStcd) fetchData();
}
);
// qxdprops.stcd
watch(
() => props.stcd,
(newStcd, oldStcd) => {
if (isQxdMode.value && newStcd && newStcd !== oldStcd) {
hasLoaded.value = false;
initData();
}
} }
); );

View File

@ -19,6 +19,7 @@
<a-empty <a-empty
v-if="!loading && videoList.length === 0" v-if="!loading && videoList.length === 0"
description="暂无数据" description="暂无数据"
class="flex align-center justify-center h-[530px] flex-col"
/> />
</a-spin> </a-spin>
</div> </div>
@ -27,7 +28,11 @@
<!-- 中间视频区域 55% --> <!-- 中间视频区域 55% -->
<a-col flex="55%" class="center-panel"> <a-col flex="55%" class="center-panel">
<!-- 视频宫格 --> <!-- 视频宫格 -->
<div class="video-grid" :class="`layout-${viewLayout}`"> <div
class="video-grid"
:class="`layout-${viewLayout}`"
v-show="videoList.length > 0"
>
<div <div
v-for="index in parseInt(viewLayout)" v-for="index in parseInt(viewLayout)"
:key="index" :key="index"
@ -42,6 +47,11 @@
/> />
</div> </div>
</div> </div>
<a-empty
v-show="videoList.length === 0"
description="暂无数据"
class="h-full flex align-center justify-center flex-col"
/>
</a-col> </a-col>
<!-- 右侧录像列表 30% --> <!-- 右侧录像列表 30% -->
@ -80,7 +90,9 @@
<div class="record-list"> <div class="record-list">
<a-spin :spinning="recordLoading"> <a-spin :spinning="recordLoading">
<div v-if="paginatedRecords.length === 0" class="empty-record"> <div v-if="paginatedRecords.length === 0" class="empty-record">
<a-empty /> <a-empty
class="h-[410px] flex align-center justify-center flex-col"
/>
</div> </div>
<div v-else class="record-grid"> <div v-else class="record-grid">
<div <div

View File

@ -12,11 +12,14 @@
<!-- 问题 <!-- 问题
1.基础信息图片展示是什么逻辑 1.基础信息图片展示是什么逻辑
2. 电站专题展示逻辑 2. 电站专题展示逻辑
3. 实时视频回放 少接口 3. 实时视频回放 少接口
4. 预警提示 少接口 4. 预警提示 少接口
5. 生态流量 达标率查询不对 5. 生态流量 达标率查询不对()
6. 鱼类适应性繁殖同期对比NAN () 6. 鱼类适应性繁殖同期对比NAN ()
7. 出库水温 综合分析 导出没做 7. 出库水温 综合分析 导出没做
8. 栖息地-流量监测 没有水位视频和流量视频 字段没数据
9. 栖息地 水温水质流量没有数据没法测
--> -->
<div v-if="modelStore.showStcdSelector" class="stcd-selector-wrapper"> <div v-if="modelStore.showStcdSelector" class="stcd-selector-wrapper">
<a-select <a-select
@ -33,7 +36,7 @@
<a-tabs :active-key="currentActiveKey" @change="onTabChange"> <a-tabs :active-key="currentActiveKey" @change="onTabChange">
<a-tab-pane v-for="tab in tabsConfig" :key="tab.key" :tab="tab.name"> <a-tab-pane v-for="tab in tabsConfig" :key="tab.key" :tab="tab.name">
</a-tab-pane> </a-tab-pane>
<template #rightExtra> <template #rightExtra v-if="anchor.sttp == 'ENG' || anchor.sttp == 'eng'">
<a-tooltip :title="!isEngConfig ? '' : '该电站无专题配置'"> <a-tooltip :title="!isEngConfig ? '' : '该电站无专题配置'">
<a-button type="primary" :disabled="isEngConfig"> <a-button type="primary" :disabled="isEngConfig">
<i class="icon iconfont icon-topic mr-[5px]"></i> <i class="icon iconfont icon-topic mr-[5px]"></i>
@ -45,6 +48,16 @@
<!-- 内容区域 - 使用动态组件 + keep-alive 实现按需加载和缓存 --> <!-- 内容区域 - 使用动态组件 + keep-alive 实现按需加载和缓存 -->
<keep-alive> <keep-alive>
<div class="content"> <div class="content">
<div class="content-wrapper" v-show="isQxdMode(currentActiveKey)">
测站
<a-select
v-model:value="currentQxdSelectedStcd"
:options="qxdStationOptions"
style="width: 200px; margin-bottom: 12px"
placeholder="请选择站点"
@change="handleQxdStationChange"
/>
</div>
<!-- 基本信息 --> <!-- 基本信息 -->
<BasicInfo <BasicInfo
v-show="currentActiveKey === 'basicInfo'" v-show="currentActiveKey === 'basicInfo'"
@ -71,12 +84,41 @@
<WaterTemperature <WaterTemperature
v-show="currentActiveKey === 'WaterTemperature'" v-show="currentActiveKey === 'WaterTemperature'"
:is-active="currentActiveKey === 'WaterTemperature'" :is-active="currentActiveKey === 'WaterTemperature'"
:code="getTabCode('WaterTemperature')"
:stcd="
getTabCode('WaterTemperature') == 'qxd.tabs.jcsj'
? qxdSelectedStcd
: ''
"
/> />
<!-- 监测数据 - 垂向水温 --> <!-- 监测数据 - 垂向水温 -->
<VerticalWaterTemperature <VerticalWaterTemperature
v-show="currentActiveKey === 'VerticalWaterTemperature'" v-show="currentActiveKey === 'VerticalWaterTemperature'"
:is-active="currentActiveKey === 'VerticalWaterTemperature'" :is-active="currentActiveKey === 'VerticalWaterTemperature'"
/> />
<!-- 监测数据 - 水质 -->
<WaterQuality
v-show="currentActiveKey === 'WaterQuality'"
:is-active="currentActiveKey === 'WaterQuality'"
:code="getTabCode('WaterQuality')"
:stcd="
getTabCode('WaterQuality') == 'qxd.tabs.szjc'
? qxdSelectedStcdWq
: ''
"
/>
<!-- 流量监测 -->
<FlowMeasure
v-show="currentActiveKey === 'FlowMeasure'"
:is-active="currentActiveKey === 'FlowMeasure'"
:url="getTabUrl('FlowMeasure')"
:code="getTabCode('FlowMeasure')"
:stcd="
getTabCode('FlowMeasure') == 'qxd.tabs.lcjs'
? qxdSelectedStcdZq
: ''
"
/>
<!-- 预警提示 --> <!-- 预警提示 -->
<EarlyWarningAlert <EarlyWarningAlert
v-show="currentActiveKey === 'tableTabs'" v-show="currentActiveKey === 'tableTabs'"
@ -123,17 +165,160 @@ import PanoramaInfo from './components/PanoramaInfo.vue'; // 全景影像
import MonitorInfo from './components/MonitorInfo.vue'; // 线 import MonitorInfo from './components/MonitorInfo.vue'; // 线
import WaterTemperature from './components/WaterTemperature.vue'; // import WaterTemperature from './components/WaterTemperature.vue'; //
import VerticalWaterTemperature from './components/VerticalWaterTemperature.vue'; // import VerticalWaterTemperature from './components/VerticalWaterTemperature.vue'; //
import WaterQuality from './components/WaterQuality.vue'; //
import EarlyWarningAlert from './components/EarlyWarningAlert.vue'; // import EarlyWarningAlert from './components/EarlyWarningAlert.vue'; //
import FlowMeasure from './components/FlowMeasure.vue'; //
import EcologicalFlow from './components/EcologicalFlow.vue'; // import EcologicalFlow from './components/EcologicalFlow.vue'; //
import Attachment from './components/Attachment.vue'; // / import Attachment from './components/Attachment.vue'; // /
import WaterTemperatureRep from './components/WaterTemperatureRep.vue'; // import WaterTemperatureRep from './components/WaterTemperatureRep.vue'; //
import { useModelStore } from '@/store/modules/model'; import { useModelStore } from '@/store/modules/model';
import { handleTabs } from './setting.config'; import { handleTabs } from './setting.config';
import {
getMonitorDataWt,
getMonitorDataWq,
getMonitorDataZq
} from '@/api/mapModal';
const modelStore = useModelStore(); const modelStore = useModelStore();
const tabsConfig = ref([]); const tabsConfig = ref([]);
// //
const isEngConfig = ref(true); const isEngConfig = ref(true);
// ==================== qxd ====================
// qxd
const qxdConfigMap: Record<
string,
{
sttpCode: string;
apiFn: (data: any) => Promise<any>;
selectProp: string;
}
> = {
'qxd.tabs.jcsj': {
//
sttpCode: 'WTRV',
apiFn: getMonitorDataWt,
selectProp: 'qxdSelectedStcd'
},
'qxd.tabs.szjc': {
//
sttpCode: 'WQ',
apiFn: getMonitorDataWq,
selectProp: 'qxdSelectedStcdWq'
},
'qxd.tabs.lcjs': {
//
sttpCode: 'ZQ',
apiFn: getMonitorDataZq,
selectProp: 'qxdSelectedStcdZq'
}
};
//
const qxdStationOptions = ref<{ label: string; value: string }[]>([]);
const qxdSelectedStcd = ref<string>('');
const qxdSelectedStcdWq = ref<string>('');
const qxdSelectedStcdZq = ref<string>('');
const qxdLoadedCodes = ref<Set<string>>(new Set());
// tabqxd
const getCurrentQxdConfig = (tabKey: string) => {
const code = getTabCode(tabKey);
return code && qxdConfigMap[code] ? qxdConfigMap[code] : null;
};
// stcd
const getQxdSelectedStcd = (tabKey: string) => {
const config = getCurrentQxdConfig(tabKey);
if (!config) return '';
switch (config.selectProp) {
case 'qxdSelectedStcd':
return qxdSelectedStcd.value;
case 'qxdSelectedStcdWq':
return qxdSelectedStcdWq.value;
case 'qxdSelectedStcdZq':
return qxdSelectedStcdZq.value;
default:
return '';
}
};
// stcd
const setQxdSelectedStcd = (tabKey: string, value: string) => {
const config = getCurrentQxdConfig(tabKey);
if (!config) return;
switch (config.selectProp) {
case 'qxdSelectedStcd':
qxdSelectedStcd.value = value;
break;
case 'qxdSelectedStcdWq':
qxdSelectedStcdWq.value = value;
break;
case 'qxdSelectedStcdZq':
qxdSelectedStcdZq.value = value;
break;
}
};
//
const loadQxdStationList = async (tabKey: string) => {
const code = getTabCode(tabKey);
if (!code || !qxdConfigMap[code]) return;
if (qxdLoadedCodes.value.has(code)) return;
const config = qxdConfigMap[code];
try {
const params = {
filter: {
logic: 'and',
filters: [
{
field: 'fhstcd',
operator: 'eq',
dataType: 'string',
value: modelStore.params.stcd
},
{
field: 'sttpCode',
operator: 'eq',
dataType: 'string',
value: config.sttpCode
}
]
},
select: ['stcd', 'stnm']
};
const res = await config.apiFn(params);
const stations = res?.data?.data || res?.data?.records || [];
if (stations.length > 0) {
qxdStationOptions.value = stations.map((item: any) => ({
label: item.stnm,
value: item.stcd
}));
setQxdSelectedStcd(tabKey, stations[0].stcd);
}
qxdLoadedCodes.value.add(code);
} catch (error) {
console.error(`获取站点列表失败(${code}):`, error);
}
};
// tabstcd (v-model)
const currentQxdSelectedStcd = computed({
get: () => getQxdSelectedStcd(currentActiveKey.value),
set: (val: string) => setQxdSelectedStcd(currentActiveKey.value, val)
});
// qxd
const isQxdMode = (tabKey: string) => {
const code = getTabCode(tabKey);
return code && qxdConfigMap[code] ? true : false;
};
//
const handleQxdStationChange = () => {
// watch stcd
};
// import MapView from './components/MapView.vue'; // import MapView from './components/MapView.vue';
// import SurroundingInfo from './components/SurroundingInfo.vue'; // import SurroundingInfo from './components/SurroundingInfo.vue';
@ -176,6 +361,7 @@ const emit = defineEmits<{
// activeKey // activeKey
const currentActiveKey = ref<string>(''); const currentActiveKey = ref<string>('');
const anchor = ref<string>('');
// activeKey // activeKey
watch( watch(
@ -192,12 +378,29 @@ watch(
newVal => { newVal => {
if (!newVal || Object.keys(newVal).length === 0) return; if (!newVal || Object.keys(newVal).length === 0) return;
console.log(newVal); console.log(newVal);
tabsConfig.value = handleTabs(newVal); anchor.value = newVal;
let params = newVal;
if (['VD', 'WTRV', 'ZQ', 'WQ'].includes(params?.sttpCode)) {
params.sttp = params.sttpCode;
}
tabsConfig.value = handleTabs({ ...params });
let value = tabsConfig.value.find((item: any) => item.default); let value = tabsConfig.value.find((item: any) => item.default);
currentActiveKey.value = value?.key; currentActiveKey.value = value?.key;
}, },
{ deep: true, immediate: true } { deep: true, immediate: true }
); );
// tab qxd
watch(
() => currentActiveKey.value,
activeKey => {
const code = getTabCode(activeKey);
if (code && qxdConfigMap[code]) {
loadQxdStationList(activeKey);
}
},
{ immediate: true }
);
// tab // tab
const onTabChange = (key: string) => { const onTabChange = (key: string) => {
currentActiveKey.value = key; currentActiveKey.value = key;
@ -213,6 +416,12 @@ const handleClose = () => {
// , // ,
modelStore.showStcdSelector = false; modelStore.showStcdSelector = false;
modelStore.stcdOptions = []; modelStore.stcdOptions = [];
// qxd
qxdStationOptions.value = [];
qxdSelectedStcd.value = '';
qxdSelectedStcdWq.value = '';
qxdSelectedStcdZq.value = '';
qxdLoadedCodes.value = new Set();
}; };
// 便使 props.data // 便使 props.data

View File

@ -320,11 +320,10 @@ const FPTabs: Array<any> =
// code: 'gyss.tabs.sssp' // code: 'gyss.tabs.sssp'
// } // }
{ {
name: '监测数据', name: '在线监测数据',
key: 'FishFacilityMonitorData', //Normal key: 'FishFacilityMonitorData', //Normal
type: 'FishFacilityMonitorData', //Normal type: 'FishFacilityMonitorData', //Normal
code: 'gyss.tabs.jcsj', code: 'gyss.tabs.jcsj'
default: true // 默认显示
// tabs: [ // tabs: [
// { // {
// name: '', // name: '',
@ -340,7 +339,8 @@ const FPTabs: Array<any> =
name: '运行情况', name: '运行情况',
key: 'FishFacilityRunState', //Normal1 key: 'FishFacilityRunState', //Normal1
type: 'FishFacilityRunState', //Normal type: 'FishFacilityRunState', //Normal
code: 'gyss.tabs.yxqk' code: 'gyss.tabs.yxqk',
default: true // 默认显示
// tabs: [ // tabs: [
// { // {
// name: '', // name: '',
@ -504,119 +504,20 @@ const FHTabs: Array<any> = [
name: '水温监测', name: '水温监测',
key: 'WaterTemperature', key: 'WaterTemperature',
type: 'WaterTemperature', type: 'WaterTemperature',
tabs: [ code: 'qxd.tabs.jcsj'
{
url: '/wmp-env-server/sw/alongDetail/GetKendoListCust',
name: '水温',
type: 'WaterTemperature',
tableUrl: '/wmp-env-server/sw/alongDetail/GetKendoListCust',
chartType: 'line',
// filter: NormalStcdFilter,
filterProps: {
params: {
ftype: 'WE',
sttp: 'WT', //WT
dataDimensionType: 'hyBase',
dataDimensionVal: 'all'
}
}
}
]
}, },
{ {
name: '水质监测', name: '水质监测',
key: 'WaterQuality', key: 'WaterQuality',
type: 'WaterQuality', type: 'WaterQuality',
tabs: [ code: 'qxd.tabs.szjc'
{
url: '/wmp-env-server/env/wq/data/GetKendoListCust',
name: '水质',
type: 'monitor',
key: 'WaterQuality',
tableUrl: '/wmp-env-server/env/wq/data/GetKendoListCust',
chartType: 'lines',
// chartEvent: {
// legendselectchanged: (object: any, instance: any) => {
// const selected = object.selected
// const options = instance.getOption()
// if (options.grid instanceof Array) {
// options.grid = options.grid[0]
// }
// if (selected != undefined && options) {
// let yAxis: any = options.yAxis
// yAxis.map((item: any, index: number) => {
// item.show = false
// for (let i in selected) {
// if (selected[i] == true && item.name.indexOf(i) !== -1) {
// item.show = true
// }
// }
// })
// options.legend && (options.legend.selected = selected)
// let offset = 30
// let padding = 60
// if (options.yAxis && options.yAxis instanceof Array && options.grid && !(options.grid instanceof Array)) {
// let showYAxis = yAxis.filter((x: any) => {
// return x.show
// })
// showYAxis.map((yAxis: any, index: number) => {
// yAxis.position = index % 2 === 0 ? "left" : "right"
// yAxis.offset = padding * Math.floor(index / 2)
// if (index >= 4) {
// yAxis.offset = padding * Math.floor(2 / 2)
// }
// })
// if (showYAxis.length % 2 === 0) {
// options.grid.left = (showYAxis.length >= 4 ? 4 : showYAxis.length) * offset
// options.grid.right = (showYAxis.length >= 4 ? 4 : showYAxis.length) * offset
// } else {
// const left = showYAxis.filter((x: any) => x.position === "left")
// const right = showYAxis.filter((x: any) => x.position === "right")
// const left_start = left.length ? 0 : 60
// const right_start = left.length ? 0 : 60
// options.grid.left = left_start + padding * (left.length >= 2 ? 2 : left.length)
// options.grid.right = right_start + padding * (right.length >= 2 ? 2 : right.length)
// }
// }
// instance.setOption(options, false, true)
// }
// }
// },
// filter: NormalStcdFilter,
filterProps: {
params: {
ftype: 'WE',
sttp: 'WQ',
dataDimensionType: 'hyBase',
dataDimensionVal: 'all'
}
}
}
]
}, },
{ {
name: '流量监测', name: '流量监测',
key: 'FlowMeasure', key: 'FlowMeasure',
type: 'FlowMeasure' type: 'FlowMeasure',
// tabs: [ code: 'qxd.tabs.lcjs',
// { url: '/zq/river/GetKendoListCust'
// url: '/wmp-eng-server/eng/river/GetKendoListCust',
// name: '流量',
// type: 'monitor',
// tableUrl: '/wmp-eng-server/eng/river/GetKendoListCust',
// chartType: 'line',
// // filter: NormalStcdFilter,
// filterProps: {
// params: {
// ftype: 'WE',
// sttp: 'ZQ',
// dataDimensionType: 'hyBase',
// dataDimensionVal: 'all',
// maptype: '2'
// }
// }
// }
// ]
}, },
{ {
name: '实时视频', name: '实时视频',
@ -624,43 +525,22 @@ const FHTabs: Array<any> = [
type: 'video', type: 'video',
url: '' url: ''
} }
// {
// name: "全景影像",
// key: "panoramaInfo",
// type: "panorama"
// }
]; ];
// const ZQTabs: Array<any> = [ const ZQTabs: Array<any> = [
// { {
// name: '基础信息', name: '基础信息',
// key: 'basicInfo', key: 'basicInfo',
// type: 'basic', type: 'basic',
// url: '/bbi/siteBipc/getSiteBasicInfo' url: '/api/dec-lygk-base-server/base/msstbprpt/getStcdInfo',
// }, default: true // 默认显示
// { },
// name: '流量监测', {
// key: 'FlowMeasure', name: '流量监测',
// type: 'FlowMeasure', key: 'FlowMeasure',
// tabs: [ type: 'FlowMeasure',
// { url: '/zq/river/GetKendoListCust'
// url: '/wmp-swqx-server/zq/river/GetKendoListCust', }
// name: '流量', ];
// type: 'monitor',
// tableUrl: '/wmp-swqx-server/zq/river/GetKendoListCust',
// chartType: 'line',
// filterProps: {
// params: {
// ftype: 'FHT',
// sttp: 'ZQ',
// dataDimensionType: 'hyBase',
// dataDimensionVal: 'all',
// maptype: '2'
// }
// }
// }
// ]
// }
// ]
// //水质监测站 √ // //水质监测站 √
const WQFBTabs: Array<any> = [ const WQFBTabs: Array<any> = [
@ -1212,8 +1092,8 @@ const handleTabs = (modaldata: any) => {
} else { } else {
return ENGTabs; return ENGTabs;
} }
case 'WT': case 'WT': // 水温
case 'WTRV': case 'WTRV': // 垂向水温
if (modaldata.enfc == '1') { if (modaldata.enfc == '1') {
return WTTabs1; return WTTabs1;
} else { } else {
@ -1340,8 +1220,8 @@ const handleTabs = (modaldata: any) => {
} else { } else {
return FPTabs; return FPTabs;
} }
// case 'ZQ': case 'ZQ': // 流量检测站
// return ZQTabs return ZQTabs;
// case 'FB': // case 'FB':
// if (modaldata.bldstt == '1' || modaldata.bldstt == '0') { // if (modaldata.bldstt == '1' || modaldata.bldstt == '0') {
// return FBTabs1 // return FBTabs1

View File

@ -146,9 +146,12 @@ export class MapOl implements MapInterface {
this.map.on('click', evt => { this.map.on('click', evt => {
this.popupManager.showPopup(undefined, undefined); this.popupManager.showPopup(undefined, undefined);
this.popupManager.handleMapClick(evt.pixel, detectedFeature => { this.popupManager.handleMapClick(evt.pixel, detectedFeature => {
console.log(detectedFeature);
modelStore.modalVisible = true; modelStore.modalVisible = true;
modelStore.params = detectedFeature.values_; modelStore.params = detectedFeature.values_;
modelStore.title = detectedFeature.values_.titleName + ' 详情信息'; modelStore.title =
detectedFeature.values_.titleName ||
detectedFeature.values_.stnm + ' 详情信息';
}); });
}); });

View File

@ -187,10 +187,11 @@ const handleControllerClick = (item: any) => {
switch (item.key) { switch (item.key) {
case 'fullScreen': case 'fullScreen':
isFullScreen.value = !isFullScreen.value; isFullScreen.value = !isFullScreen.value;
map.flyTopanto([92.39728, 29.24587], 14);
// console.log(mapClass.hasLayer('eng_point')); // console.log(mapClass.hasLayer('eng_point'));
// map.jdPanelControlShowAndHidden("01", false); // map.jdPanelControlShowAndHidden("01", false);
map.mdLayerTreeShowOrHidden('eng_point', false); // map.mdLayerTreeShowOrHidden('eng_point', false);
map.mdLayerTreeShowOrHidden('wq_countryWq_point', true); // map.mdLayerTreeShowOrHidden('wq_countryWq_point', true);
// map.controlBaseLayerTreeShowAndHidden( // map.controlBaseLayerTreeShowAndHidden(
// 'eng_point', // 'eng_point',
// 'eng_point', // 'eng_point',

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,6 @@ service.interceptors.request.use(
config.url.includes('/wmp-eng-server') || config.url.includes('/wmp-eng-server') ||
config.url.includes('/dec-modules-usm-springcloud-starter') || config.url.includes('/dec-modules-usm-springcloud-starter') ||
config.url.includes('/wmp-swqx-server') config.url.includes('/wmp-swqx-server')
) { ) {
config.headers._appid = '974975A6-47FD-4C04-9ACD-68938D2992BD'; config.headers._appid = '974975A6-47FD-4C04-9ACD-68938D2992BD';
config.headers._isolateid = '5b34aecb-adfb-4dfc-ad95-21505a9eb388'; config.headers._isolateid = '5b34aecb-adfb-4dfc-ad95-21505a9eb388';
@ -34,7 +33,7 @@ service.interceptors.request.use(
config.headers._sysid = '10EC2E0B-AEA9-4757-83A2-201BA1BC54E9'; config.headers._sysid = '10EC2E0B-AEA9-4757-83A2-201BA1BC54E9';
config.headers.authorization = config.headers.authorization =
'bearer 7894f05d-7204-4117-bda5-8d2f850ae463'; 'bearer f6ce5036-cefe-487b-b731-b6d7b8922e0f';
config.baseURL = '/'; config.baseURL = '/';
} else { } else {
const user = useUserStoreHook(); const user = useUserStoreHook();

File diff suppressed because it is too large Load Diff