Merge branch 'main' into dev-lilin
This commit is contained in:
commit
e5dcdaf299
@ -7,7 +7,7 @@ VITE_APP_TITLE = '水电水利建设项目全过程环境管理信息平台'
|
|||||||
VITE_APP_PORT = 3000
|
VITE_APP_PORT = 3000
|
||||||
VITE_APP_BASE_API = '/dev-api'
|
VITE_APP_BASE_API = '/dev-api'
|
||||||
# 本地环境
|
# 本地环境
|
||||||
# VITE_APP_BASE_URL = 'http://10.84.121.122:8093'
|
# VITE_APP_BASE_URL = 'http://172.16.54.1:8093'
|
||||||
# 测试环境
|
# 测试环境
|
||||||
# VITE_APP_BASE_URL = 'http://172.16.21.142:8093'
|
# VITE_APP_BASE_URL = 'http://172.16.21.142:8093'
|
||||||
# VITE_APP_BASE_URL = 'http://172.16.21.142:8096'
|
# VITE_APP_BASE_URL = 'http://172.16.21.142:8096'
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
import request from '@/utils/request';
|
import request from '@/utils/request';
|
||||||
// import { SERVICE_URLS } from '../config'; // 引入配置
|
|
||||||
// 基本情况介绍
|
// 基本情况介绍
|
||||||
export function getBaseWbsb(data: any) {
|
export function getBaseWbsb(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/dec-lygk-base-server/base/wbsb/GetKendoList',
|
url: '/eq/wbsb/GetKendoList',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data
|
data: data
|
||||||
});
|
});
|
||||||
@ -12,7 +11,16 @@ export function getBaseWbsb(data: any) {
|
|||||||
// 水电开发及环境监测 - 获取列表数据
|
// 水电开发及环境监测 - 获取列表数据
|
||||||
export function getVmsstbprptKendoList(data: any) {
|
export function getVmsstbprptKendoList(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/dec-lygk-base-server/base/vmsstbprpt/GetKendoList',
|
url: '/eq/vmsstbprpt/GetKendoList',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 水电开发及环境监测 - 获取列表数据(全基地模式)
|
||||||
|
export function getVmsstbprptKendoListCust(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/eq/vmsstbprpt/GetKendoList',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data
|
data: data
|
||||||
});
|
});
|
||||||
@ -21,7 +29,7 @@ export function getVmsstbprptKendoList(data: any) {
|
|||||||
// 环保设施建设情况
|
// 环保设施建设情况
|
||||||
export function environmentalProtectionConstruction(data: any) {
|
export function environmentalProtectionConstruction(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/wmp-env-server/env/operat/GetKendoListCust',
|
url: '/eng/base/operat/GetKendoListCust',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data
|
data: data
|
||||||
});
|
});
|
||||||
@ -30,7 +38,7 @@ export function environmentalProtectionConstruction(data: any) {
|
|||||||
// 环保设施弹框表格
|
// 环保设施弹框表格
|
||||||
export function envOpdGetKendoListCust(data: any) {
|
export function envOpdGetKendoListCust(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/wmp-env-server/env/oped/GetKendoListCust',
|
url: '/overview/oped/GetKendoListCust',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data
|
data: data
|
||||||
});
|
});
|
||||||
@ -39,7 +47,7 @@ export function envOpdGetKendoListCust(data: any) {
|
|||||||
// 获取基地列表
|
// 获取基地列表
|
||||||
export function getBaseList(data: any) {
|
export function getBaseList(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/dec-lygk-base-server/base/wbsb/GetKendoList',
|
url: '/eq/wbsb/GetKendoList',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data
|
data: data
|
||||||
});
|
});
|
||||||
@ -48,7 +56,7 @@ export function getBaseList(data: any) {
|
|||||||
// 获取设施介绍列表
|
// 获取设施介绍列表
|
||||||
export function getMsstbprptKendoList(data: any) {
|
export function getMsstbprptKendoList(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/dec-lygk-base-server/base/msstbprpt/GetKendoList',
|
url: '/overview/msstbprpt/GetKendoList',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data
|
data: data
|
||||||
});
|
});
|
||||||
@ -57,7 +65,7 @@ export function getMsstbprptKendoList(data: any) {
|
|||||||
// 环保自动监测工作开展情况
|
// 环保自动监测工作开展情况
|
||||||
export function baseEvnmAutoMonitorGetKendoListCust(data: any) {
|
export function baseEvnmAutoMonitorGetKendoListCust(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/dec-lygk-base-server/base/evnmAutoMonitor/GetKendoListCust',
|
url: '/wte/base/evnmAutoMonitor/GetKendoListCust',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data
|
data: data
|
||||||
});
|
});
|
||||||
@ -66,7 +74,7 @@ export function baseEvnmAutoMonitorGetKendoListCust(data: any) {
|
|||||||
// 环保自动监测弹窗列表
|
// 环保自动监测弹窗列表
|
||||||
export function vmsstbprptGetKendoList(data: any) {
|
export function vmsstbprptGetKendoList(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/dec-lygk-base-server/base/vmsstbprpt/GetKendoList',
|
url: '/eq/vmsstbprpt/GetKendoList',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data
|
data: data
|
||||||
});
|
});
|
||||||
@ -75,7 +83,7 @@ export function vmsstbprptGetKendoList(data: any) {
|
|||||||
// 获取基本信息
|
// 获取基本信息
|
||||||
export function baseMsstbprptGetKendoList(data: any) {
|
export function baseMsstbprptGetKendoList(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/dec-lygk-base-server/base/msstbprpt/GetKendoList',
|
url: '/overview/msstbprpt/GetKendoList',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data
|
data: data
|
||||||
});
|
});
|
||||||
@ -106,4 +114,4 @@ export function getBaseStbprpDataWNDR(data: any) {
|
|||||||
method: 'post',
|
method: 'post',
|
||||||
data: data
|
data: data
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -28,7 +28,7 @@ export function postIdUrl(data: any) {
|
|||||||
method: 'post',
|
method: 'post',
|
||||||
data,
|
data,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'multipart/form-data'
|
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,25 +3,25 @@ import request from '@/utils/request';
|
|||||||
// AI识别大坝环境-获取统计数据(Tab数量)
|
// AI识别大坝环境-获取统计数据(Tab数量)
|
||||||
export function getAisbdbyxList(data: any) {
|
export function getAisbdbyxList(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/wmp-env-server/env/ai/com/qgcDmRun/GetKendoListCust',
|
url: '/warn/ai/com/qgcDmRun/GetKendoListCust',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// AI识别大坝环境-获取饼图+表格数据
|
// AI识别大坝环境-获取饼图+表格数据 /api/wmp-env-server/env/ai/com/GetKendoListCust
|
||||||
export function getAiChartTable(data: any) {
|
export function getAiChartTable(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/wmp-env-server/env/ai/com/GetKendoListCust',
|
url: '/warn/ai/com/GetKendoListCust',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// AI识别大坝环境-获取电站列表
|
// AI识别大坝环境-获取电站列表
|
||||||
export function getAiRstcd(data: any) {
|
export function getAiRstcd(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/wmp-env-server/env/ai/com/qgc/aiRstcd/GetKendoListCust',
|
url: '/warn/ai/com/qgc/aiRstcd/GetKendoListCust',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
@ -30,7 +30,7 @@ export function getAiRstcd(data: any) {
|
|||||||
// AI识别过鱼设施运行-获取统计数据
|
// AI识别过鱼设施运行-获取统计数据
|
||||||
export function getAiGyssList(data: any) {
|
export function getAiGyssList(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/wmp-env-server/env/ai/com/qgcProtect/GetKendoListCust',
|
url: '/warn/ai/com/qgcProtect/GetKendoListCust',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
@ -39,7 +39,7 @@ export function getAiGyssList(data: any) {
|
|||||||
// 生态流量低于限值告警-获取统计数据
|
// 生态流量低于限值告警-获取统计数据
|
||||||
export function getStllGaojingList(data: any) {
|
export function getStllGaojingList(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/wmp-env-server/env/warn/stcd/eng/GetKendoListCust',
|
url: '/warn/stcd/eng/GetKendoListCust',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
@ -48,7 +48,7 @@ export function getStllGaojingList(data: any) {
|
|||||||
// 生态流量低于限值告警-获取表格详情数据
|
// 生态流量低于限值告警-获取表格详情数据
|
||||||
export function getStllGaojingDetail(data: any) {
|
export function getStllGaojingDetail(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/wmp-env-server/env/warn/stcd/GetKendoListCust',
|
url: '/warn/stcd/GetKendoListCust',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
@ -57,7 +57,7 @@ export function getStllGaojingDetail(data: any) {
|
|||||||
// 水质监测数据告警-获取统计数据
|
// 水质监测数据告警-获取统计数据
|
||||||
export function getShuizhiGaojingList(data: any) {
|
export function getShuizhiGaojingList(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/dec-lygk-base-server/base/msstbprpt/GetKendoList',
|
url: '/wq/msstbprpt/GetKendoList',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
@ -66,7 +66,7 @@ export function getShuizhiGaojingList(data: any) {
|
|||||||
// AI识别大坝环境-获取漂浮物/清漂日历数据
|
// AI识别大坝环境-获取漂浮物/清漂日历数据
|
||||||
export function getAiPfwRecord(data: any) {
|
export function getAiPfwRecord(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/wmp-env-server/env/ai/com/qgc/aiPfwRecord/GetKendoListCust',
|
url: '/warn/ai/com/qgc/aiPfwRecord/GetKendoListCust',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
@ -75,16 +75,16 @@ export function getAiPfwRecord(data: any) {
|
|||||||
// AI识别大坝环境-获取叠梁门日历数据
|
// AI识别大坝环境-获取叠梁门日历数据
|
||||||
export function getAiRecord(data: any) {
|
export function getAiRecord(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/wmp-env-server/env/ai/com/qgc/aiRecord/GetKendoListCust',
|
url: '/warn/ai/com/qgc/aiRecord/GetKendoListCust',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// AI识别大坝环境-获取日历详情视频数据
|
// AI识别大坝环境-获取日历详情视频数据 /warn/ai/com/qgc/aiFile/GetKendoListCust
|
||||||
export function getAiFile(data: any) {
|
export function getAiFile(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/wmp-env-server/env/ai/com/qgc/aiFile/GetKendoListCust',
|
url: '/warn/ai/com/qgc/aiFile/GetKendoListCust',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,6 +2,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="basic_body">
|
<div class="basic_body">
|
||||||
<div ref="chartContainer" class="chart-container"></div>
|
<div ref="chartContainer" class="chart-container"></div>
|
||||||
|
|
||||||
|
<!-- 水电开发情况弹窗 -->
|
||||||
|
<a-modal
|
||||||
|
v-model:open="modalVisible"
|
||||||
|
title="水电开发情况"
|
||||||
|
width="1536px"
|
||||||
|
:footer="null"
|
||||||
|
:destroy-on-close="true"
|
||||||
|
>
|
||||||
|
<ShuiDianKaiFQKTwoLayer
|
||||||
|
v-if="modalVisible"
|
||||||
|
:defaultJidiInfo="modalProps.defaultJidiInfo"
|
||||||
|
:seriesName="modalProps.seriesName"
|
||||||
|
:stateName="modalProps.stateName"
|
||||||
|
:defaultTab="modalProps.defaultTab"
|
||||||
|
/>
|
||||||
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -10,21 +27,31 @@ import { ref, onMounted, onUnmounted, watch } from 'vue';
|
|||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
import { getVmsstbprptKendoList } from '@/api/home';
|
import { getVmsstbprptKendoList } from '@/api/home';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
|
import ShuiDianKaiFQKTwoLayer from '@/modules/shuidianhuangjingjieruMod/TwoLayer/ShuiDianKaiFQKTwoLayer.vue';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'developStatusChart'
|
name: 'developStatusChart'
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: 'chart-click', params: any): void;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
const baseid = ref('');
|
const baseid = ref('');
|
||||||
const chartContainer = ref<HTMLDivElement | null>(null);
|
const chartContainer = ref<HTMLDivElement | null>(null);
|
||||||
let chartInstance: echarts.ECharts | null = null;
|
let chartInstance: echarts.ECharts | null = null;
|
||||||
const dataLoading = ref(false);
|
const dataLoading = ref(false);
|
||||||
|
|
||||||
|
const modalVisible = ref(false);
|
||||||
|
const modalProps = ref<any>({});
|
||||||
|
|
||||||
|
function openModal(props: any) {
|
||||||
|
modalProps.value = props;
|
||||||
|
modalVisible.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
openModal,
|
||||||
|
dataLoading
|
||||||
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
if (chartInstance) {
|
if (chartInstance) {
|
||||||
chartInstance.dispose();
|
chartInstance.dispose();
|
||||||
@ -75,7 +102,6 @@ const getData = async () => {
|
|||||||
|
|
||||||
const res1Data = res1?.data?.data || [];
|
const res1Data = res1?.data?.data || [];
|
||||||
const res2Data = res2?.data?.data || [];
|
const res2Data = res2?.data?.data || [];
|
||||||
// debugger
|
|
||||||
|
|
||||||
if (res1Data.length > 0 || res2Data.length > 0) {
|
if (res1Data.length > 0 || res2Data.length > 0) {
|
||||||
const ttpwrlist = res1Data.map((item: any) => ({
|
const ttpwrlist = res1Data.map((item: any) => ({
|
||||||
@ -234,12 +260,16 @@ const initChart = () => {
|
|||||||
|
|
||||||
chartInstance.setOption(option);
|
chartInstance.setOption(option);
|
||||||
|
|
||||||
// 添加点击事件
|
|
||||||
chartInstance.on('click', (params: any) => {
|
chartInstance.on('click', (params: any) => {
|
||||||
emit('chart-click', {
|
const currentJidiInfo = JidiSelectEventStore.selectedItem;
|
||||||
|
openModal({
|
||||||
|
defaultJidiInfo: {
|
||||||
|
baseid: currentJidiInfo?.wbsCode || 'all',
|
||||||
|
basename: currentJidiInfo?.wbsName || '全部基地'
|
||||||
|
},
|
||||||
seriesName: params.seriesName,
|
seriesName: params.seriesName,
|
||||||
name: params.name,
|
stateName: params.name,
|
||||||
dataIndex: params.dataIndex
|
defaultTab: params.name
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -38,6 +38,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<a-modal
|
||||||
|
v-model:open="modalVisible"
|
||||||
|
title="环境监测数据接入情况"
|
||||||
|
width="1536px"
|
||||||
|
:footer="null"
|
||||||
|
:destroy-on-close="true"
|
||||||
|
>
|
||||||
|
<HuanJingSJJRQK
|
||||||
|
v-if="modalVisible"
|
||||||
|
:dataDimensionVal="modalProps.dataDimensionVal"
|
||||||
|
:name="modalProps.name"
|
||||||
|
/>
|
||||||
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -45,20 +59,30 @@
|
|||||||
import { ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
import { getVmsstbprptKendoList } from '@/api/home';
|
import { getVmsstbprptKendoList } from '@/api/home';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
|
import HuanJingSJJRQK from '@/modules/shuidianhuangjingjieruMod/TwoLayer/HuanJingSJJRQK.vue';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'EngEnvironmentData'
|
name: 'EngEnvironmentData'
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: 'item-click', params: any): void;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
const baseid = ref('');
|
const baseid = ref('');
|
||||||
const dataLoading = ref(false);
|
const dataLoading = ref(false);
|
||||||
const data = ref<Record<string, number>>({ one: 0, two: 0, three: 0 });
|
const data = ref<Record<string, number>>({ one: 0, two: 0, three: 0 });
|
||||||
|
|
||||||
|
const modalVisible = ref(false);
|
||||||
|
const modalProps = ref<any>({});
|
||||||
|
|
||||||
|
function openModal(props: any) {
|
||||||
|
modalProps.value = props;
|
||||||
|
modalVisible.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
openModal,
|
||||||
|
dataLoading
|
||||||
|
});
|
||||||
|
|
||||||
const getData = async () => {
|
const getData = async () => {
|
||||||
if (!baseid.value) return;
|
if (!baseid.value) return;
|
||||||
|
|
||||||
@ -77,7 +101,8 @@ const getData = async () => {
|
|||||||
...baseFilters,
|
...baseFilters,
|
||||||
{ field: 'prsc', operator: 'in', dataType: 'string', value: ['1', '2', '3'] }
|
{ field: 'prsc', operator: 'in', dataType: 'string', value: ['1', '2', '3'] }
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
group: [{ dir: 'desc', field: 'sttpCode' }]
|
||||||
};
|
};
|
||||||
|
|
||||||
const params2 = {
|
const params2 = {
|
||||||
@ -88,7 +113,8 @@ const getData = async () => {
|
|||||||
{ field: 'runState', operator: 'eq', dataType: 'number', value: 4 },
|
{ field: 'runState', operator: 'eq', dataType: 'number', value: 4 },
|
||||||
{ field: 'dtin', operator: 'eq', dataType: 'number', value: 1 }
|
{ field: 'dtin', operator: 'eq', dataType: 'number', value: 1 }
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
group: [{ dir: 'desc', field: 'sttpCode' }]
|
||||||
};
|
};
|
||||||
|
|
||||||
const params3 = {
|
const params3 = {
|
||||||
@ -99,7 +125,8 @@ const getData = async () => {
|
|||||||
{ field: 'prsc', operator: 'in', dataType: 'string', value: ['1', '2', '3'] },
|
{ field: 'prsc', operator: 'in', dataType: 'string', value: ['1', '2', '3'] },
|
||||||
{ field: 'dtinEnv', operator: 'in', dataType: 'string', value: ['2'] }
|
{ field: 'dtinEnv', operator: 'in', dataType: 'string', value: ['2'] }
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
group: [{ dir: 'desc', field: 'dtinEnv' }]
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -113,21 +140,22 @@ const getData = async () => {
|
|||||||
const record = { one: 0, two: 0, three: 0 };
|
const record = { one: 0, two: 0, three: 0 };
|
||||||
const responses = [res1, res2, res3];
|
const responses = [res1, res2, res3];
|
||||||
responses.forEach((res, index) => {
|
responses.forEach((res, index) => {
|
||||||
const total = res?.data?.total ?? 0;
|
if (res?.data?.data && Array.isArray(res.data.data) && res.data.data.length > 0) {
|
||||||
switch (index) {
|
const count = res.data.data[0].count ?? 0;
|
||||||
case 0:
|
switch (index) {
|
||||||
record.one = total;
|
case 0:
|
||||||
break;
|
record.one = count;
|
||||||
case 1:
|
break;
|
||||||
record.two = total;
|
case 1:
|
||||||
break;
|
record.two = count;
|
||||||
case 2:
|
break;
|
||||||
record.three = total;
|
case 2:
|
||||||
break;
|
record.three = count;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
data.value = record;
|
data.value = record;
|
||||||
// debugger
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('EngEnvironmentData getData error:', error);
|
console.error('EngEnvironmentData getData error:', error);
|
||||||
} finally {
|
} finally {
|
||||||
@ -136,7 +164,11 @@ const getData = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleItemClick = (name: string) => {
|
const handleItemClick = (name: string) => {
|
||||||
emit('item-click', { name });
|
const currentJidiInfo = JidiSelectEventStore.selectedItem;
|
||||||
|
openModal({
|
||||||
|
dataDimensionVal: currentJidiInfo?.wbsCode || 'all',
|
||||||
|
name
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
|||||||
@ -21,6 +21,14 @@
|
|||||||
:options="jiDiList"
|
:options="jiDiList"
|
||||||
@change="handleBaseChange"
|
@change="handleBaseChange"
|
||||||
/>
|
/>
|
||||||
|
<a-select
|
||||||
|
v-model:value="searchData.stcd"
|
||||||
|
placeholder=" "
|
||||||
|
style="width: 200px"
|
||||||
|
show-search
|
||||||
|
:filter-option="filterOption"
|
||||||
|
:options="rstcdOptions"
|
||||||
|
/>
|
||||||
<a-input
|
<a-input
|
||||||
v-if="tabIndex !== '7'"
|
v-if="tabIndex !== '7'"
|
||||||
v-model:value="searchData.stnm"
|
v-model:value="searchData.stnm"
|
||||||
@ -44,7 +52,6 @@
|
|||||||
:search-params="searchParams"
|
:search-params="searchParams"
|
||||||
:transform-data="customTransform"
|
:transform-data="customTransform"
|
||||||
>
|
>
|
||||||
|
|
||||||
<template #coenvwState="{ column, record }">
|
<template #coenvwState="{ column, record }">
|
||||||
<a-tag :color="record.coenvwState > 0 ? 'green' : '#999'">
|
<a-tag :color="record.coenvwState > 0 ? 'green' : '#999'">
|
||||||
{{ record.coenvwState > 0 ? '在线' : '离线' }}
|
{{ record.coenvwState > 0 ? '在线' : '离线' }}
|
||||||
@ -85,13 +92,15 @@ const props = defineProps<{
|
|||||||
const tabIndex = ref(String(props.activeKey ?? ''));
|
const tabIndex = ref(String(props.activeKey ?? ''));
|
||||||
const searchData = ref<any>({
|
const searchData = ref<any>({
|
||||||
baseId: props.baseId || 'all',
|
baseId: props.baseId || 'all',
|
||||||
stnm: null
|
stnm: null,
|
||||||
|
stcd: null
|
||||||
});
|
});
|
||||||
const modelStore = useModelStore();
|
const modelStore = useModelStore();
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
|
|
||||||
// ==================== 基地列表数据 ====================
|
// ==================== 基地列表数据 ====================
|
||||||
const jiDiList: any = ref([]);
|
const jiDiList: any = ref([]);
|
||||||
|
const rstcdOptions: any = ref([]);
|
||||||
|
|
||||||
// ==================== 表格列定义 ====================
|
// ==================== 表格列定义 ====================
|
||||||
const columns = computed(() => {
|
const columns = computed(() => {
|
||||||
@ -103,29 +112,27 @@ const columns = computed(() => {
|
|||||||
title: '所属基地',
|
title: '所属基地',
|
||||||
dataIndex: 'baseName',
|
dataIndex: 'baseName',
|
||||||
width: '150px',
|
width: '150px',
|
||||||
merge: true
|
merge: true
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'stnm',
|
key: 'stnm',
|
||||||
title: '电站名称',
|
title: '电站名称',
|
||||||
dataIndex: 'stnm',
|
dataIndex: 'stnm',
|
||||||
width: '176px',
|
width: '176px'
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'dvtp',
|
key: 'dvtp',
|
||||||
title: '开发方式',
|
title: '开发方式',
|
||||||
dataIndex: 'dvtp',
|
dataIndex: 'dvtp',
|
||||||
width: '120px',
|
width: '120px',
|
||||||
|
|
||||||
slots: { customRender: 'dvtp' }
|
slots: { customRender: 'dvtp' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'stindx',
|
key: 'stindx',
|
||||||
title: '生态流量站类型',
|
title: '生态流量站类型',
|
||||||
dataIndex: 'stindx',
|
dataIndex: 'stindx',
|
||||||
|
|
||||||
slots: { customRender: 'stindxForEng' }
|
slots: { customRender: 'stindxForEng' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -140,7 +147,7 @@ const columns = computed(() => {
|
|||||||
title: '监测状态',
|
title: '监测状态',
|
||||||
dataIndex: 'coenvwState',
|
dataIndex: 'coenvwState',
|
||||||
width: '120px',
|
width: '120px',
|
||||||
|
|
||||||
slots: { customRender: 'coenvwState' }
|
slots: { customRender: 'coenvwState' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -167,15 +174,14 @@ const columns = computed(() => {
|
|||||||
key: 'stnm',
|
key: 'stnm',
|
||||||
title: '测站名称',
|
title: '测站名称',
|
||||||
dataIndex: 'stnm',
|
dataIndex: 'stnm',
|
||||||
width: '176px',
|
width: '176px'
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'ennm',
|
key: 'ennm',
|
||||||
title: '电站',
|
title: '电站',
|
||||||
dataIndex: 'ennm',
|
dataIndex: 'ennm',
|
||||||
width: '150px',
|
width: '150px',
|
||||||
|
|
||||||
slots: { customRender: 'ennm' }
|
slots: { customRender: 'ennm' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -189,8 +195,7 @@ const columns = computed(() => {
|
|||||||
key: 'stindx',
|
key: 'stindx',
|
||||||
title: '监测指标',
|
title: '监测指标',
|
||||||
dataIndex: 'stindx',
|
dataIndex: 'stindx',
|
||||||
width: '150px',
|
width: '150px'
|
||||||
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -260,15 +265,66 @@ const searchParams = computed(() => {
|
|||||||
// ==================== 方法 ====================
|
// ==================== 方法 ====================
|
||||||
const handleTabChange = (key: string) => {
|
const handleTabChange = (key: string) => {
|
||||||
tabIndex.value = key;
|
tabIndex.value = key;
|
||||||
|
handleReset();
|
||||||
handleSearch();
|
handleSearch();
|
||||||
};
|
};
|
||||||
|
|
||||||
const filterOption = (input: string, option: any) => {
|
const filterOption = (input: string, option: any) => {
|
||||||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||||
};
|
};
|
||||||
|
const getRstcdData = async () => {
|
||||||
|
const parmas = {
|
||||||
|
filter: {
|
||||||
|
logic: 'and',
|
||||||
|
filters: [
|
||||||
|
searchData.value.baseId != 'all'
|
||||||
|
? {
|
||||||
|
field: 'baseId',
|
||||||
|
operator: 'contains',
|
||||||
|
dataType: 'string',
|
||||||
|
value: '02'
|
||||||
|
}
|
||||||
|
: 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']
|
||||||
|
};
|
||||||
|
const res = await vmsstbprptGetKendoList(parmas);
|
||||||
|
rstcdOptions.value = res.data.data.map((item) => {
|
||||||
|
return {
|
||||||
|
value: item.stcd,
|
||||||
|
label: item.stnm
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
const handleBaseChange = () => {
|
const handleBaseChange = () => {
|
||||||
handleSearch();
|
searchData.value.stcd = null
|
||||||
|
getRstcdData();
|
||||||
|
// handleSearch();
|
||||||
};
|
};
|
||||||
|
|
||||||
const dvtpText = (dvtp: number) => {
|
const dvtpText = (dvtp: number) => {
|
||||||
@ -287,7 +343,13 @@ const handleSearch = () => {
|
|||||||
value: searchData.value.baseId
|
value: searchData.value.baseId
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if(searchData.value.stcd){
|
||||||
|
filters.push({
|
||||||
|
field: 'stcd',
|
||||||
|
operator: 'eq',
|
||||||
|
value: searchData.value.stcd
|
||||||
|
});
|
||||||
|
}
|
||||||
if (searchData.value.stnm) {
|
if (searchData.value.stnm) {
|
||||||
filters.push({
|
filters.push({
|
||||||
field: 'stnm',
|
field: 'stnm',
|
||||||
@ -441,8 +503,10 @@ const handleSearch = () => {
|
|||||||
const handleReset = () => {
|
const handleReset = () => {
|
||||||
searchData.value = {
|
searchData.value = {
|
||||||
baseId: 'all',
|
baseId: 'all',
|
||||||
stnm: null
|
stnm: null,
|
||||||
|
stcd: null
|
||||||
};
|
};
|
||||||
|
getRstcdData()
|
||||||
handleSearch();
|
handleSearch();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -542,7 +606,7 @@ const handleViewDetail = (record: any, type: string) => {
|
|||||||
sttpCode === 'WTVT' || sttpCode === 'WTVT,' ? '1' : '0';
|
sttpCode === 'WTVT' || sttpCode === 'WTVT,' ? '1' : '0';
|
||||||
} else {
|
} else {
|
||||||
modelStore.modalVisible = true;
|
modelStore.modalVisible = true;
|
||||||
modelStore.params.sttp = sttpCode;
|
modelStore.params.sttp = sttpCode;
|
||||||
modelStore.params.stcd = record.stcd;
|
modelStore.params.stcd = record.stcd;
|
||||||
modelStore.title = record.stnm;
|
modelStore.title = record.stnm;
|
||||||
}
|
}
|
||||||
@ -557,6 +621,7 @@ onMounted(() => {
|
|||||||
value: element.wbsCode
|
value: element.wbsCode
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
getRstcdData()
|
||||||
handleSearch();
|
handleSearch();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
1956
frontend/src/modules/liuyu/ai/spdzwaijc/AISPTK.vue
Normal file
1956
frontend/src/modules/liuyu/ai/spdzwaijc/AISPTK.vue
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,317 @@
|
|||||||
|
<template>
|
||||||
|
<div class="video-details">
|
||||||
|
<a-tabs v-model:activeKey="activeKey" @change="handleTabChange">
|
||||||
|
<a-tab-pane key="2" tab="运行">
|
||||||
|
<a-spin :spinning="loading">
|
||||||
|
<div class="video-container">
|
||||||
|
<VideoPlayer
|
||||||
|
:list="videoList"
|
||||||
|
:activeFid="activeFid"
|
||||||
|
:activeMedia="activeMedia"
|
||||||
|
:loading="loading"
|
||||||
|
:page="page"
|
||||||
|
:pageSize="pageSize"
|
||||||
|
:pageSizeOptions="pageSizeOptions"
|
||||||
|
:total="total"
|
||||||
|
@select="handleSelectMedia"
|
||||||
|
@pageChange="handlePageChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</a-spin>
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane key="1" tab="未运行">
|
||||||
|
<a-spin :spinning="loading">
|
||||||
|
<div class="video-container">
|
||||||
|
<VideoPlayer
|
||||||
|
:list="videoList"
|
||||||
|
:activeFid="activeFid"
|
||||||
|
:activeMedia="activeMedia"
|
||||||
|
:loading="loading"
|
||||||
|
:page="page"
|
||||||
|
:pageSize="pageSize"
|
||||||
|
:pageSizeOptions="pageSizeOptions"
|
||||||
|
:total="total"
|
||||||
|
@select="handleSelectMedia"
|
||||||
|
@pageChange="handlePageChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</a-spin>
|
||||||
|
</a-tab-pane>
|
||||||
|
</a-tabs>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, watch, onMounted } from 'vue';
|
||||||
|
import VideoPlayer from '@/modules/yunXingGaoJIng/Aisbdbyx/components/VideoPlayer.vue';
|
||||||
|
import { getAiFile } from '@/api/zngj';
|
||||||
|
import { postIdUrl } from '@/api/mapModal';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
const baseUrl = import.meta.env.VITE_APP_ATTACHMENT_URL;
|
||||||
|
|
||||||
|
// ==================== Props ====================
|
||||||
|
const props = defineProps<{
|
||||||
|
baseid?: string;
|
||||||
|
month?: any;
|
||||||
|
type?: string;
|
||||||
|
vdDate?: string;
|
||||||
|
activeKey?: string;
|
||||||
|
stnm?: string;
|
||||||
|
rstcd?: string;
|
||||||
|
pieCode?: string[];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
// ==================== 状态 ====================
|
||||||
|
const activeKey = ref(props.activeKey || '2');
|
||||||
|
const loading = ref(false);
|
||||||
|
const videoList = ref<any[]>([]);
|
||||||
|
const activeFid = ref('');
|
||||||
|
const activeMedia = ref<{ type: string; src: string }>({ type: '', src: '' });
|
||||||
|
const page = ref(1);
|
||||||
|
const pageSize = ref(20);
|
||||||
|
const pageSizeOptions = ['20', '50', '100'];
|
||||||
|
const total = ref(0);
|
||||||
|
|
||||||
|
// ==================== 获取视频列表 ====================
|
||||||
|
const fetchVideoList = async () => {
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const filters: any[] = [
|
||||||
|
// baseId过滤
|
||||||
|
props.pieCode && props.pieCode.length > 0 && props.baseid === 'all'
|
||||||
|
? {
|
||||||
|
field: 'baseId',
|
||||||
|
operator: 'in',
|
||||||
|
dataType: 'string',
|
||||||
|
value: props.pieCode
|
||||||
|
}
|
||||||
|
: props.baseid && props.baseid !== 'all'
|
||||||
|
? { field: 'baseId', operator: 'eq', value: props.baseid }
|
||||||
|
: null,
|
||||||
|
// rstcd过滤
|
||||||
|
props.pieCode && props.pieCode.length > 0 && props.baseid !== 'all'
|
||||||
|
? {
|
||||||
|
field: 'rstcd',
|
||||||
|
operator: 'in',
|
||||||
|
dataType: 'string',
|
||||||
|
value: props.pieCode
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
// type过滤
|
||||||
|
{ field: 'type', operator: 'eq', value: props.type },
|
||||||
|
// dataType过滤(运行/未运行)
|
||||||
|
{ field: 'dataType', operator: 'eq', value: activeKey.value },
|
||||||
|
// 时间范围(按天)
|
||||||
|
{
|
||||||
|
field: 'tm',
|
||||||
|
operator: 'gte',
|
||||||
|
dataType: 'date',
|
||||||
|
value: dayjs(props.vdDate)
|
||||||
|
.startOf('day')
|
||||||
|
.format('YYYY-MM-DD 00:00:00')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'tm',
|
||||||
|
operator: 'lte',
|
||||||
|
dataType: 'date',
|
||||||
|
value: dayjs(props.vdDate)
|
||||||
|
.endOf('day')
|
||||||
|
.format('YYYY-MM-DD 23:59:59')
|
||||||
|
},
|
||||||
|
// stnm文本搜索
|
||||||
|
props.stnm
|
||||||
|
? { field: 'stnm', operator: 'contains', value: props.stnm }
|
||||||
|
: null,
|
||||||
|
// rstcd电站选择
|
||||||
|
props.rstcd
|
||||||
|
? {
|
||||||
|
field: 'rstcd',
|
||||||
|
operator: 'in',
|
||||||
|
dataType: 'string',
|
||||||
|
value: [props.rstcd]
|
||||||
|
}
|
||||||
|
: null
|
||||||
|
].filter(Boolean);
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
filter: { logic: 'and', filters },
|
||||||
|
sort: [{ field: 'tm', dir: 'desc' }],
|
||||||
|
skip: (page.value - 1) * pageSize.value,
|
||||||
|
take: pageSize.value
|
||||||
|
};
|
||||||
|
|
||||||
|
const res: any = await getAiFile(params);
|
||||||
|
const rData = res?.data ?? {};
|
||||||
|
const rawData = rData?.data || [];
|
||||||
|
total.value = rData?.total || rawData.length;
|
||||||
|
|
||||||
|
// 按 fid 展开
|
||||||
|
const expandedData = rawData
|
||||||
|
.map((item: any) => {
|
||||||
|
const fids = item.fid ? item.fid.split(',') : [];
|
||||||
|
return fids.map((fid: string) => ({ ...item, fid: fid.trim() }));
|
||||||
|
})
|
||||||
|
.flat();
|
||||||
|
|
||||||
|
// 收集所有 fid
|
||||||
|
const allFids = expandedData
|
||||||
|
.filter((item: any) => item.fid)
|
||||||
|
.map((item: any) => item.fid)
|
||||||
|
.join(',');
|
||||||
|
|
||||||
|
// 调用 postIdUrl 获取媒体详情
|
||||||
|
let mediaMap: Record<string, any> = {};
|
||||||
|
if (allFids) {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('id', allFids);
|
||||||
|
const mediaRes: any = await postIdUrl(formData);
|
||||||
|
mediaMap = mediaRes?.data || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建列表
|
||||||
|
const list: any[] = [];
|
||||||
|
expandedData.forEach((vd: any) => {
|
||||||
|
const fileInfo = mediaMap[vd.fid];
|
||||||
|
const hasValidExtension =
|
||||||
|
fileInfo && ['.jpg', '.png'].includes(fileInfo.ext);
|
||||||
|
|
||||||
|
let flpth = '';
|
||||||
|
let imgPath = '';
|
||||||
|
let type = '';
|
||||||
|
|
||||||
|
if (hasValidExtension !== undefined && !hasValidExtension) {
|
||||||
|
flpth = fileInfo.fullpath;
|
||||||
|
type = 'vdsp';
|
||||||
|
} else if (hasValidExtension !== undefined) {
|
||||||
|
imgPath = fileInfo.fullpath;
|
||||||
|
type = 'img';
|
||||||
|
}
|
||||||
|
|
||||||
|
const tm = vd.tm ? dayjs(vd.tm).format('YYYY-MM-DD HH:mm:ss') : '-';
|
||||||
|
list.push({
|
||||||
|
...vd,
|
||||||
|
flpth,
|
||||||
|
imgPath,
|
||||||
|
flnm: `${vd.ennm || ''}${tm}`,
|
||||||
|
type,
|
||||||
|
tm
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 过滤掉无效项
|
||||||
|
const listMap = list.filter(
|
||||||
|
item => item.flpth !== '' || item.imgPath !== ''
|
||||||
|
);
|
||||||
|
videoList.value = listMap;
|
||||||
|
|
||||||
|
// 默认选中第一条
|
||||||
|
if (listMap.length > 0) {
|
||||||
|
const first = listMap[0];
|
||||||
|
activeFid.value = first.fid;
|
||||||
|
if (first.type === 'img') {
|
||||||
|
activeMedia.value = {
|
||||||
|
type: 'image',
|
||||||
|
src: baseUrl + '?' + first.fid + '&view=jpg'
|
||||||
|
};
|
||||||
|
} else if (first.type === 'vdsp') {
|
||||||
|
activeMedia.value = {
|
||||||
|
type: 'video',
|
||||||
|
src: baseUrl + '?' + first.fid + '&view=jpg'
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
activeMedia.value = { type: '', src: '' };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
activeFid.value = '';
|
||||||
|
activeMedia.value = { type: '', src: '' };
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取视频详情列表失败:', error);
|
||||||
|
videoList.value = [];
|
||||||
|
activeFid.value = '';
|
||||||
|
activeMedia.value = { type: '', src: '' };
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ==================== 事件处理 ====================
|
||||||
|
const handleTabChange = () => {
|
||||||
|
page.value = 1;
|
||||||
|
activeFid.value = '';
|
||||||
|
activeMedia.value = { type: '', src: '' };
|
||||||
|
fetchVideoList();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSelectMedia = (item: any) => {
|
||||||
|
activeFid.value = item.fid;
|
||||||
|
|
||||||
|
if (item.type === 'img') {
|
||||||
|
activeMedia.value = {
|
||||||
|
type: 'image',
|
||||||
|
src: baseUrl + '?' + item.fid + '&view=jpg'
|
||||||
|
};
|
||||||
|
} else if (item.type === 'vdsp') {
|
||||||
|
activeMedia.value = {
|
||||||
|
type: 'video',
|
||||||
|
src: baseUrl + '?' + item.fid + '&view=jpg'
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
activeMedia.value = { type: '', src: '' };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePageChange = (newPage: number, newPageSize: number) => {
|
||||||
|
page.value = newPage;
|
||||||
|
pageSize.value = newPageSize;
|
||||||
|
activeFid.value = '';
|
||||||
|
activeMedia.value = { type: '', src: '' };
|
||||||
|
fetchVideoList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// ==================== 监听 ====================
|
||||||
|
watch(
|
||||||
|
() => [props.vdDate, props.type, activeKey.value],
|
||||||
|
() => {
|
||||||
|
if (props.vdDate) {
|
||||||
|
page.value = 1;
|
||||||
|
fetchVideoList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// ==================== 生命周期 ====================
|
||||||
|
onMounted(() => {
|
||||||
|
if (props.vdDate) {
|
||||||
|
fetchVideoList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.video-details {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
:deep(.ant-tabs) {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-tabs-content) {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-tabs-tabpane) {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-container {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -3,7 +3,12 @@
|
|||||||
<SidePanelItem title="AI识别过鱼设施运行" :datetimePicker="datetimePicker" @update-values="handlePanelChange">
|
<SidePanelItem title="AI识别过鱼设施运行" :datetimePicker="datetimePicker" @update-values="handlePanelChange">
|
||||||
<a-spin :spinning="dataLoading" tip="加载中...">
|
<a-spin :spinning="dataLoading" tip="加载中...">
|
||||||
<div class="facility-grid">
|
<div class="facility-grid">
|
||||||
<div v-for="facility in facilities" :key="facility.key" class="facility-card">
|
<div
|
||||||
|
v-for="facility in facilities"
|
||||||
|
:key="facility.key"
|
||||||
|
class="facility-card"
|
||||||
|
@click="handleCardClick(facility.action)"
|
||||||
|
>
|
||||||
<div style="width: 70px;height: 62px;display: flex;align-items: center;justify-content: center;">
|
<div style="width: 70px;height: 62px;display: flex;align-items: center;justify-content: center;">
|
||||||
<div class="facility-icon">
|
<div class="facility-icon">
|
||||||
<i style="color: #fff;" :class="facility.icon" type="icon-shengtailiuliang2"></i>
|
<i style="color: #fff;" :class="facility.icon" type="icon-shengtailiuliang2"></i>
|
||||||
@ -20,12 +25,30 @@
|
|||||||
</div>
|
</div>
|
||||||
</a-spin>
|
</a-spin>
|
||||||
</SidePanelItem>
|
</SidePanelItem>
|
||||||
|
|
||||||
|
<!-- AI识别过鱼设施运行详情弹框 -->
|
||||||
|
<a-modal
|
||||||
|
v-model:open="modalVisible"
|
||||||
|
title="AI识别过鱼设施运行"
|
||||||
|
width="1536px"
|
||||||
|
:footer="null"
|
||||||
|
@cancel="handleModalClose"
|
||||||
|
>
|
||||||
|
<AISPTK
|
||||||
|
v-if="modalVisible"
|
||||||
|
:month="datetimePicker.value"
|
||||||
|
:action="currentAction"
|
||||||
|
:baseid="baseid"
|
||||||
|
:ly-name="lyName"
|
||||||
|
/>
|
||||||
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, computed, watch } from 'vue';
|
import { ref, computed, watch } from 'vue';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||||
|
import AISPTK from './AISPTK.vue';
|
||||||
import { getAiGyssList } from '@/api/zngj';
|
import { getAiGyssList } from '@/api/zngj';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
@ -39,6 +62,10 @@ const baseid = ref('');
|
|||||||
const dataLoading = ref(false);
|
const dataLoading = ref(false);
|
||||||
const panelDetail = ref<any>({});
|
const panelDetail = ref<any>({});
|
||||||
|
|
||||||
|
// ==================== 弹框状态 ====================
|
||||||
|
const modalVisible = ref(false);
|
||||||
|
const currentAction = ref('AI_5006');
|
||||||
|
|
||||||
const lyName = computed(() => baseid.value === '02' ? '升鱼斗运行' : '升鱼机运行');
|
const lyName = computed(() => baseid.value === '02' ? '升鱼斗运行' : '升鱼机运行');
|
||||||
|
|
||||||
// ==================== 日期选择器配置 ====================
|
// ==================== 日期选择器配置 ====================
|
||||||
@ -56,37 +83,43 @@ const facilities = computed(() => [
|
|||||||
key: 'gys',
|
key: 'gys',
|
||||||
name: '赶鱼栅运行',
|
name: '赶鱼栅运行',
|
||||||
count: panelDetail.value?.fpGysCnt ?? 0,
|
count: panelDetail.value?.fpGysCnt ?? 0,
|
||||||
icon: 'icon iconfont icon-ganyushan'
|
icon: 'icon iconfont icon-ganyushan',
|
||||||
|
action: 'AI_5006'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'syj',
|
key: 'syj',
|
||||||
name: lyName.value,
|
name: lyName.value,
|
||||||
count: panelDetail.value?.fpSyjCnt ?? 0,
|
count: panelDetail.value?.fpSyjCnt ?? 0,
|
||||||
icon: 'icon iconfont icon-liuliangjiancezhan1'
|
icon: 'icon iconfont icon-liuliangjiancezhan1',
|
||||||
|
action: 'AI_5007'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'agv',
|
key: 'agv',
|
||||||
name: 'AGV小车',
|
name: 'AGV小车',
|
||||||
count: panelDetail.value?.fpAgvCnt ?? 0,
|
count: panelDetail.value?.fpAgvCnt ?? 0,
|
||||||
icon: 'icon iconfont icon-agvxiaoche'
|
icon: 'icon iconfont icon-agvxiaoche',
|
||||||
|
action: 'AI_5008'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'yych',
|
key: 'yych',
|
||||||
name: '运鱼车运行',
|
name: '运鱼车运行',
|
||||||
count: panelDetail.value?.fpYychCnt ?? 0,
|
count: panelDetail.value?.fpYychCnt ?? 0,
|
||||||
icon: 'icon iconfont icon-yunyuche'
|
icon: 'icon iconfont icon-yunyuche',
|
||||||
|
action: 'AI_5002'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'yyc',
|
key: 'yyc',
|
||||||
name: '运鱼船出港',
|
name: '运鱼船出港',
|
||||||
count: panelDetail.value?.fpYycCnt ?? 0,
|
count: panelDetail.value?.fpYycCnt ?? 0,
|
||||||
icon: 'icon iconfont icon-yunyuchuan'
|
icon: 'icon iconfont icon-yunyuchuan',
|
||||||
|
action: 'AI_5003'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'ydh',
|
key: 'ydh',
|
||||||
name: '鱼道放流',
|
name: '鱼道放流',
|
||||||
count: panelDetail.value?.fpYdhCnt ?? 0,
|
count: panelDetail.value?.fpYdhCnt ?? 0,
|
||||||
icon: 'icon iconfont icon-yudaofangliu'
|
icon: 'icon iconfont icon-yudaofangliu',
|
||||||
|
action: 'AI_5012'
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -99,6 +132,15 @@ const handlePanelChange = (data: any) => {
|
|||||||
getCardData();
|
getCardData();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleCardClick = (action: string) => {
|
||||||
|
currentAction.value = action;
|
||||||
|
modalVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleModalClose = () => {
|
||||||
|
modalVisible.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
// ==================== 获取卡片统计数据 ====================
|
// ==================== 获取卡片统计数据 ====================
|
||||||
const getCardData = async () => {
|
const getCardData = async () => {
|
||||||
if (!datetimePicker.value.value || !baseid.value) return;
|
if (!datetimePicker.value.value || !baseid.value) return;
|
||||||
|
|||||||
@ -4,6 +4,21 @@
|
|||||||
<a-table :columns="columns" :data-source="tableData" :pagination="false" size="middle" :customRow="customRow"
|
<a-table :columns="columns" :data-source="tableData" :pagination="false" size="middle" :customRow="customRow"
|
||||||
:loading="dataLoading" bordered class="custom-table">
|
:loading="dataLoading" bordered class="custom-table">
|
||||||
</a-table>
|
</a-table>
|
||||||
|
<a-modal
|
||||||
|
v-model:open="modalVisible"
|
||||||
|
title="水电开发情况"
|
||||||
|
width="1536px"
|
||||||
|
:footer="null"
|
||||||
|
:destroy-on-close="true"
|
||||||
|
>
|
||||||
|
<ShuiDianKaiFQKTwoLayer
|
||||||
|
v-if="modalVisible"
|
||||||
|
:defaultJidiInfo="modalProps.defaultJidiInfo"
|
||||||
|
:seriesName="modalProps.seriesName"
|
||||||
|
:stateName="modalProps.stateName"
|
||||||
|
:defaultTab="modalProps.defaultTab"
|
||||||
|
/>
|
||||||
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -11,6 +26,7 @@
|
|||||||
import { ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
import { getVmsstbprptKendoList } from '@/api/home';
|
import { getVmsstbprptKendoList } from '@/api/home';
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
|
import ShuiDianKaiFQKTwoLayer from './TwoLayer/ShuiDianKaiFQKTwoLayer.vue';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'DataTable'
|
name: 'DataTable'
|
||||||
@ -25,6 +41,26 @@ const baseid = ref('');
|
|||||||
const dataLoading = ref(false);
|
const dataLoading = ref(false);
|
||||||
const tableData = ref<any[]>([]);
|
const tableData = ref<any[]>([]);
|
||||||
|
|
||||||
|
const modalVisible = ref(false);
|
||||||
|
const modalProps = ref<any>({});
|
||||||
|
|
||||||
|
const openDialog = (record: any) => {
|
||||||
|
const currentJidiInfo = JidiSelectEventStore.selectedItem;
|
||||||
|
const isAll = currentJidiInfo?.wbsCode === 'all';
|
||||||
|
const stateName = record.bldsttCcode === '0' ? '未建' : record.bldsttCcode === '1' ? '在建' : '已建';
|
||||||
|
|
||||||
|
modalProps.value = {
|
||||||
|
defaultJidiInfo: {
|
||||||
|
baseid: isAll ? record.key : currentJidiInfo?.wbsCode || 'all',
|
||||||
|
basename: isAll ? record.name : currentJidiInfo?.wbsName || '全部基地'
|
||||||
|
},
|
||||||
|
seriesName: '装机容量(万kW)',
|
||||||
|
stateName,
|
||||||
|
defaultTab: stateName
|
||||||
|
};
|
||||||
|
modalVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
const columns = ref([
|
const columns = ref([
|
||||||
{
|
{
|
||||||
title: '基地名称',
|
title: '基地名称',
|
||||||
@ -183,6 +219,7 @@ const customRow = (record: any, index: number) => {
|
|||||||
},
|
},
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
if (record.name !== '总计') {
|
if (record.name !== '总计') {
|
||||||
|
openDialog(record);
|
||||||
emit('row-click', record);
|
emit('row-click', record);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,58 +1,24 @@
|
|||||||
<!-- SidePanelItem.vue -->
|
|
||||||
<template>
|
<template>
|
||||||
<div class="basic_body">
|
<div class="basic_body">
|
||||||
<SidePanelItem title="大中型水电开发及环境监测数据接入情况" :prompt="prompt">
|
<SidePanelItem title="大中型水电开发及环境监测数据接入情况" >
|
||||||
<div>
|
<div>
|
||||||
<div class="body_top">
|
<div class="body_top">
|
||||||
<!-- {/* 水电开发情况图表 */} -->
|
|
||||||
<div style="flex: 1;">
|
<div style="flex: 1;">
|
||||||
<div>水电开发情况</div>
|
<div>水电开发情况</div>
|
||||||
<div style="color: #757575;font-size: 12px;line-height: 16px;">图释:数量(内)/装机容量(外)</div>
|
<div style="color: #757575;font-size: 12px;line-height: 16px;">图释:数量(内)/装机容量(外)</div>
|
||||||
<div>
|
<a-spin :spinning="developStatusChartRef?.dataLoading">
|
||||||
<DevelopStatusChart @chart-click="handleChartClick" />
|
<DevelopStatusChart ref="developStatusChartRef" />
|
||||||
</div>
|
</a-spin>
|
||||||
</div>
|
</div>
|
||||||
<!-- style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center" }} -->
|
|
||||||
<div style="flex: 1;display: flex; flex-direction: column; align-items: center;">
|
<div style="flex: 1;display: flex; flex-direction: column; align-items: center;">
|
||||||
<EngEnvironmentData @item-click="handleEnvItemClick" />
|
<a-spin :spinning="engEnvironmentDataRef?.dataLoading">
|
||||||
|
<EngEnvironmentData ref="engEnvironmentDataRef" />
|
||||||
|
</a-spin>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<DataTable @row-click="handleRowClick" />
|
<DataTable />
|
||||||
</div>
|
</div>
|
||||||
<!-- <div v-else class="zanwushujv"> <a-empty /></div> -->
|
|
||||||
</SidePanelItem>
|
</SidePanelItem>
|
||||||
|
|
||||||
<!-- 水电开发情况弹窗 -->
|
|
||||||
<a-modal
|
|
||||||
v-model:open="shuidianModalVisible"
|
|
||||||
:title="shuidianModalTitle"
|
|
||||||
width="1536px"
|
|
||||||
:footer="null"
|
|
||||||
:destroy-on-close="true"
|
|
||||||
>
|
|
||||||
<ShuiDianKaiFQKTwoLayer
|
|
||||||
v-if="shuidianModalVisible"
|
|
||||||
:defaultJidiInfo="shuidianModalProps.defaultJidiInfo"
|
|
||||||
:seriesName="shuidianModalProps.seriesName"
|
|
||||||
:stateName="shuidianModalProps.stateName"
|
|
||||||
:defaultTab="shuidianModalProps.defaultTab"
|
|
||||||
/>
|
|
||||||
</a-modal>
|
|
||||||
|
|
||||||
<!-- 环境监测数据接入情况弹窗 -->
|
|
||||||
<a-modal
|
|
||||||
v-model:open="huanjingModalVisible"
|
|
||||||
:title="huanjingModalTitle"
|
|
||||||
width="1536px"
|
|
||||||
:footer="null"
|
|
||||||
:destroy-on-close="true"
|
|
||||||
>
|
|
||||||
<HuanJingSJJRQK
|
|
||||||
v-if="huanjingModalVisible"
|
|
||||||
:dataDimensionVal="huanjingModalProps.dataDimensionVal"
|
|
||||||
:name="huanjingModalProps.name"
|
|
||||||
/>
|
|
||||||
</a-modal>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -62,36 +28,21 @@ import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
|||||||
import DevelopStatusChart from "@/components/developStatusChart/index.vue"
|
import DevelopStatusChart from "@/components/developStatusChart/index.vue"
|
||||||
import EngEnvironmentData from "@/components/engEnvironmentData/index.vue"
|
import EngEnvironmentData from "@/components/engEnvironmentData/index.vue"
|
||||||
import DataTable from "./DataTable.vue"
|
import DataTable from "./DataTable.vue"
|
||||||
import ShuiDianKaiFQKTwoLayer from "./TwoLayer/ShuiDianKaiFQKTwoLayer.vue"
|
|
||||||
import HuanJingSJJRQK from "./TwoLayer/HuanJingSJJRQK.vue"
|
|
||||||
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
|
||||||
|
import { Spin } from 'ant-design-vue';
|
||||||
|
|
||||||
// 定义组件名(便于调试和递归)
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'shuidianhuangjingjieruMod'
|
name: 'shuidianhuangjingjieruMod'
|
||||||
});
|
});
|
||||||
|
|
||||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||||
|
|
||||||
const prompt = ref({
|
const developStatusChartRef = ref<InstanceType<typeof DevelopStatusChart> | null>(null);
|
||||||
show: true,
|
const engEnvironmentDataRef = ref<InstanceType<typeof EngEnvironmentData> | null>(null);
|
||||||
value: '统计大中型已建,在建水电站',
|
|
||||||
})
|
|
||||||
|
|
||||||
// 水电开发情况弹窗状态
|
|
||||||
const shuidianModalVisible = ref(false);
|
|
||||||
const shuidianModalTitle = ref('水电开发情况');
|
|
||||||
const shuidianModalProps = ref<any>({});
|
|
||||||
|
|
||||||
// 环境监测数据接入情况弹窗状态
|
|
||||||
const huanjingModalVisible = ref(false);
|
|
||||||
const huanjingModalTitle = ref('环境监测数据接入情况');
|
|
||||||
const huanjingModalProps = ref<any>({});
|
|
||||||
|
|
||||||
// DataTable 行点击事件
|
|
||||||
const handleRowClick = (record: any) => {
|
const handleRowClick = (record: any) => {
|
||||||
const currentJidiInfo = JidiSelectEventStore.selectedItem;
|
const currentJidiInfo = JidiSelectEventStore.selectedItem;
|
||||||
shuidianModalProps.value = {
|
developStatusChartRef.value?.openModal({
|
||||||
defaultJidiInfo: {
|
defaultJidiInfo: {
|
||||||
baseid: currentJidiInfo?.wbsCode || 'all',
|
baseid: currentJidiInfo?.wbsCode || 'all',
|
||||||
basename: currentJidiInfo?.wbsName || '全部基地'
|
basename: currentJidiInfo?.wbsName || '全部基地'
|
||||||
@ -99,41 +50,10 @@ const handleRowClick = (record: any) => {
|
|||||||
seriesName: currentJidiInfo?.wbsCode === 'other' ? '数量(座)' : '装机容量(万kW)',
|
seriesName: currentJidiInfo?.wbsCode === 'other' ? '数量(座)' : '装机容量(万kW)',
|
||||||
stateName: record.bldsttCcode === '0' ? '未建' : record.bldsttCcode === '1' ? '在建' : '已建',
|
stateName: record.bldsttCcode === '0' ? '未建' : record.bldsttCcode === '1' ? '在建' : '已建',
|
||||||
defaultTab: record.bldsttCcode === '0' ? '未建' : record.bldsttCcode === '1' ? '在建' : '已建'
|
defaultTab: record.bldsttCcode === '0' ? '未建' : record.bldsttCcode === '1' ? '在建' : '已建'
|
||||||
};
|
});
|
||||||
shuidianModalTitle.value = '水电开发情况';
|
|
||||||
shuidianModalVisible.value = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// DevelopStatusChart 饼图点击事件
|
|
||||||
const handleChartClick = (params: any) => {
|
|
||||||
const currentJidiInfo = JidiSelectEventStore.selectedItem;
|
|
||||||
shuidianModalProps.value = {
|
|
||||||
defaultJidiInfo: {
|
|
||||||
baseid: currentJidiInfo?.wbsCode || 'all',
|
|
||||||
basename: currentJidiInfo?.wbsName || '全部基地'
|
|
||||||
},
|
|
||||||
seriesName: params.seriesName,
|
|
||||||
stateName: params.name,
|
|
||||||
defaultTab: params.name
|
|
||||||
};
|
|
||||||
shuidianModalTitle.value = '水电开发情况';
|
|
||||||
shuidianModalVisible.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// EngEnvironmentData 指标点击事件
|
|
||||||
const handleEnvItemClick = (params: any) => {
|
|
||||||
const currentJidiInfo = JidiSelectEventStore.selectedItem;
|
|
||||||
huanjingModalProps.value = {
|
|
||||||
dataDimensionVal: currentJidiInfo?.wbsCode || 'all',
|
|
||||||
name: params.name
|
|
||||||
};
|
|
||||||
huanjingModalTitle.value = '环境监测数据接入情况';
|
|
||||||
huanjingModalVisible.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 页面加载时执行的逻辑
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -142,4 +62,4 @@ onMounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,218 @@
|
|||||||
|
<template>
|
||||||
|
<div class="video-section">
|
||||||
|
<div class="video-mode">
|
||||||
|
<div class="video-main" v-loading="loading">
|
||||||
|
<div v-if="activeMedia.type === 'image' && activeMedia.src" class="media-display">
|
||||||
|
<img :src="activeMedia.src" style="width: 100%; height: 100%; object-fit: contain" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="activeMedia.type === 'video' && activeMedia.src" class="media-display">
|
||||||
|
<LiveVideoBox :videoData="{ url: activeMedia.src }" height="100%" :showTitle="false" />
|
||||||
|
</div>
|
||||||
|
<div v-else class="media-empty">
|
||||||
|
<a-empty :description="emptyText" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="video-sidebar" v-loading="loading">
|
||||||
|
<div class="sidebar-list" v-if="list.length > 0">
|
||||||
|
<div
|
||||||
|
v-for="item in list"
|
||||||
|
:key="item.fid"
|
||||||
|
class="sidebar-item"
|
||||||
|
:class="{ active: activeFid === item.fid }"
|
||||||
|
@click="handleSelect(item)"
|
||||||
|
>
|
||||||
|
<div class="item-thumb">
|
||||||
|
<img v-if="item.type === 'img'" :src="item.imgPath" />
|
||||||
|
<div v-else-if="item.type === 'vdsp'" class="thumb-placeholder">
|
||||||
|
<img :src="videoCover" />
|
||||||
|
</div>
|
||||||
|
<span v-else class="no-media">无媒体</span>
|
||||||
|
</div>
|
||||||
|
<div class="item-time">{{ item.stName || item.ennm }}{{ item.tm }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a-empty v-else description="暂无数据" class="sidebar-empty" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="sidebar-pagination" style="margin-top: 10px; display: flex; justify-content: end">
|
||||||
|
<a-pagination
|
||||||
|
v-model:current="currentPage"
|
||||||
|
v-model:pageSize="currentPageSize"
|
||||||
|
:page-size-options="pageSizeOptions"
|
||||||
|
:total="total"
|
||||||
|
show-size-changer
|
||||||
|
size="small"
|
||||||
|
@change="handlePageChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, watch } from 'vue';
|
||||||
|
import LiveVideoBox from '@/views/shiPinJianKong/components/LiveVideoBox.vue';
|
||||||
|
import videoCover from '@/assets/images/videFm.jpg';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
list: any[];
|
||||||
|
activeFid: string;
|
||||||
|
activeMedia: { type: string; src: string };
|
||||||
|
loading: boolean;
|
||||||
|
page: number;
|
||||||
|
pageSize: number;
|
||||||
|
pageSizeOptions: string[];
|
||||||
|
total: number;
|
||||||
|
emptyText?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
emptyText: '请选择右侧数据'
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'select', item: any): void;
|
||||||
|
(e: 'pageChange', page: number, pageSize: number): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const currentPage = ref(props.page);
|
||||||
|
const currentPageSize = ref(props.pageSize);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.page,
|
||||||
|
val => {
|
||||||
|
currentPage.value = val;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.pageSize,
|
||||||
|
val => {
|
||||||
|
currentPageSize.value = val;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleSelect = (item: any) => {
|
||||||
|
emit('select', item);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePageChange = (page: number, pageSize: number) => {
|
||||||
|
currentPage.value = page;
|
||||||
|
currentPageSize.value = pageSize;
|
||||||
|
emit('pageChange', page, pageSize);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
.video-mode {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
width: 100%;
|
||||||
|
height: 520px;
|
||||||
|
|
||||||
|
.video-main {
|
||||||
|
flex: 0 0 80%;
|
||||||
|
background: #000;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.media-display {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-empty {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-sidebar {
|
||||||
|
flex: 0 0 20%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border: 1px solid #e8e8e8;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.sidebar-list {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.sidebar-item {
|
||||||
|
padding: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
transition: background 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: #e6f7ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-thumb {
|
||||||
|
width: 100%;
|
||||||
|
height: 110px;
|
||||||
|
background: #1a1a1a;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
.no-media {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-time {
|
||||||
|
margin-top: 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-empty {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-pagination {
|
||||||
|
padding: 8px;
|
||||||
|
text-align: center;
|
||||||
|
border-top: 1px solid #e8e8e8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 样式继承自父组件 */
|
||||||
|
</style>
|
||||||
@ -0,0 +1,119 @@
|
|||||||
|
import * as echarts from 'echarts';
|
||||||
|
import type { ECharts, EChartsOption } from 'echarts';
|
||||||
|
|
||||||
|
export interface ChartDataItem {
|
||||||
|
name: string;
|
||||||
|
value: number;
|
||||||
|
key: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function usePieChart(
|
||||||
|
chartRefs: Map<string, HTMLElement>,
|
||||||
|
chartData: { value: ChartDataItem[] },
|
||||||
|
tabIndex: { value: string },
|
||||||
|
typeMap: Record<string, string>,
|
||||||
|
legendCallback?: (e: any) => void
|
||||||
|
) {
|
||||||
|
let chartInstance: ECharts | null = null;
|
||||||
|
|
||||||
|
const initChart = (retryCount = 0) => {
|
||||||
|
const dom = chartRefs.get(tabIndex.value);
|
||||||
|
if (!dom) {
|
||||||
|
if (retryCount < 10) {
|
||||||
|
setTimeout(() => initChart(retryCount + 1), 100);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rect = dom.getBoundingClientRect();
|
||||||
|
if (rect.width === 0 || rect.height === 0) {
|
||||||
|
if (retryCount < 10) {
|
||||||
|
setTimeout(() => initChart(retryCount + 1), 100);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!chartInstance) {
|
||||||
|
chartInstance = echarts.init(dom);
|
||||||
|
}
|
||||||
|
|
||||||
|
const option: EChartsOption = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item',
|
||||||
|
formatter: (params: any) => `${params.marker} ${params.name}: ${params.value}(次)`
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
orient: 'vertical',
|
||||||
|
right: 10,
|
||||||
|
top: 80,
|
||||||
|
textStyle: { fontSize: 12 }
|
||||||
|
},
|
||||||
|
series: []
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!chartData.value || chartData.value.length === 0) {
|
||||||
|
chartInstance.setOption(option, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const total = chartData.value.reduce((acc: number, item: ChartDataItem) => acc + (item.value || 0), 0);
|
||||||
|
const titleText = typeMap[tabIndex.value] || '识别(次)';
|
||||||
|
|
||||||
|
option.series = [
|
||||||
|
{
|
||||||
|
type: 'pie',
|
||||||
|
radius: ['26%', '35%'],
|
||||||
|
center: ['35%', '50%'],
|
||||||
|
avoidLabelOverlap: false,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
formatter: '{c}'
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: true,
|
||||||
|
length: 12,
|
||||||
|
length2: 12
|
||||||
|
},
|
||||||
|
data: chartData.value.map((item: ChartDataItem) => ({
|
||||||
|
name: item.name,
|
||||||
|
value: item.value
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
option.title = {
|
||||||
|
text: String(total),
|
||||||
|
left: '34%',
|
||||||
|
top: '44%',
|
||||||
|
textAlign: 'center',
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 24,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: '#333'
|
||||||
|
},
|
||||||
|
subtext: titleText,
|
||||||
|
subtextStyle: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: '#333'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
chartInstance.setOption(option, true);
|
||||||
|
|
||||||
|
if (legendCallback) {
|
||||||
|
chartInstance.off('legendselectchanged');
|
||||||
|
chartInstance.on('legendselectchanged', legendCallback);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const dispose = () => {
|
||||||
|
chartInstance?.dispose();
|
||||||
|
chartInstance = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const resize = () => {
|
||||||
|
chartInstance?.resize();
|
||||||
|
};
|
||||||
|
|
||||||
|
return { initChart, dispose, resize };
|
||||||
|
}
|
||||||
@ -0,0 +1,131 @@
|
|||||||
|
import { ref } from 'vue';
|
||||||
|
import { postIdUrl } from '@/api/mapModal';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
export interface VideoListItem {
|
||||||
|
fid: string;
|
||||||
|
media: any;
|
||||||
|
thumbUrl: string;
|
||||||
|
isVideo: boolean;
|
||||||
|
isImage: boolean;
|
||||||
|
tm: string;
|
||||||
|
ennm?: string;
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useVideoList(
|
||||||
|
fetchFn: (params: any) => Promise<any>,
|
||||||
|
baseUrl: string
|
||||||
|
) {
|
||||||
|
const page = ref(1);
|
||||||
|
const take = ref(20);
|
||||||
|
const total = ref(0);
|
||||||
|
const loading = ref(false);
|
||||||
|
const list = ref<VideoListItem[]>([]);
|
||||||
|
const activeFid = ref('');
|
||||||
|
const activeMedia = ref<{ type: string; src: string }>({ type: '', src: '' });
|
||||||
|
|
||||||
|
const fetchList = async (filter: any, options: any = {}) => {
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const skip = (page.value - 1) * take.value;
|
||||||
|
const params = { filter, skip, take: take.value, ...options };
|
||||||
|
const res = await fetchFn(params);
|
||||||
|
const dataObj = res?.data?.data ?? {};
|
||||||
|
const rawData = dataObj?.data || [];
|
||||||
|
total.value = dataObj?.total || 0;
|
||||||
|
|
||||||
|
const allFids: string[] = [];
|
||||||
|
rawData.forEach((item: any) => {
|
||||||
|
if (item.fid) {
|
||||||
|
item.fid.split(',').forEach((f: string) => {
|
||||||
|
const trimmed = f.trim();
|
||||||
|
if (trimmed) allFids.push(trimmed);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let mediaMap: Record<string, any> = {};
|
||||||
|
if (allFids.length > 0) {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('id', allFids.join(','));
|
||||||
|
const mediaRes: any = await postIdUrl(formData);
|
||||||
|
mediaMap = mediaRes?.data || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const flatList: VideoListItem[] = [];
|
||||||
|
rawData.forEach((item: any) => {
|
||||||
|
const fids = item.fid
|
||||||
|
? item.fid.split(',').map((f: string) => f.trim()).filter(Boolean)
|
||||||
|
: [];
|
||||||
|
const tm = item.tm ? dayjs(item.tm).format('YYYY-MM-DD HH:mm:ss') : '-';
|
||||||
|
|
||||||
|
fids.forEach((fid: string) => {
|
||||||
|
const m = mediaMap[fid];
|
||||||
|
const ext = m?.ext || '';
|
||||||
|
const isVideo = ext === '.mp4';
|
||||||
|
const isImage = ext === '.jpg' || ext === '.png';
|
||||||
|
|
||||||
|
flatList.push({
|
||||||
|
...item,
|
||||||
|
fid,
|
||||||
|
media: m || null,
|
||||||
|
thumbUrl: isImage ? baseUrl + '?' + fid + '&view=jpg' : '',
|
||||||
|
isVideo,
|
||||||
|
isImage,
|
||||||
|
tm
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
list.value = flatList;
|
||||||
|
|
||||||
|
if (list.value.length > 0 && !activeFid.value) {
|
||||||
|
selectMedia(list.value[0]);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取视频列表失败:', error);
|
||||||
|
list.value = [];
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectMedia = (item: VideoListItem) => {
|
||||||
|
activeFid.value = item.fid;
|
||||||
|
const { isVideo, isImage } = item;
|
||||||
|
|
||||||
|
if (isImage) {
|
||||||
|
activeMedia.value = { type: 'image', src: baseUrl + '?' + item.fid + '&view=jpg' };
|
||||||
|
} else if (isVideo) {
|
||||||
|
activeMedia.value = { type: 'video', src: baseUrl + '?' + item.fid + '&view=jpg' };
|
||||||
|
} else {
|
||||||
|
activeMedia.value = { type: '', src: '' };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePageChange = () => {
|
||||||
|
activeFid.value = '';
|
||||||
|
activeMedia.value = { type: '', src: '' };
|
||||||
|
};
|
||||||
|
|
||||||
|
const reset = () => {
|
||||||
|
page.value = 1;
|
||||||
|
activeFid.value = '';
|
||||||
|
activeMedia.value = { type: '', src: '' };
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
page,
|
||||||
|
take,
|
||||||
|
total,
|
||||||
|
loading,
|
||||||
|
list,
|
||||||
|
activeFid,
|
||||||
|
activeMedia,
|
||||||
|
fetchList,
|
||||||
|
selectMedia,
|
||||||
|
handlePageChange,
|
||||||
|
reset
|
||||||
|
};
|
||||||
|
}
|
||||||
60
frontend/src/modules/yunXingGaoJIng/Aisbdbyx/types/index.ts
Normal file
60
frontend/src/modules/yunXingGaoJIng/Aisbdbyx/types/index.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
export enum TabType {
|
||||||
|
PFW = '1',
|
||||||
|
DLM = '2',
|
||||||
|
QP = '3'
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum AiType {
|
||||||
|
PFW = 'AI_5001',
|
||||||
|
DLM = 'AI_5005',
|
||||||
|
QP = 'AI_5011'
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ChartDataItem {
|
||||||
|
name: string;
|
||||||
|
value: number;
|
||||||
|
key: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VideoListItem {
|
||||||
|
fid: string;
|
||||||
|
media: any;
|
||||||
|
thumbUrl: string;
|
||||||
|
isVideo: boolean;
|
||||||
|
isImage: boolean;
|
||||||
|
tm: string;
|
||||||
|
ennm?: string;
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CalendarDayData {
|
||||||
|
dt: string;
|
||||||
|
status?: string;
|
||||||
|
qpStatus?: string;
|
||||||
|
fid?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CalendarStatusInfo {
|
||||||
|
name: string;
|
||||||
|
className: string;
|
||||||
|
type: string;
|
||||||
|
dataType: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TabItem {
|
||||||
|
key: number;
|
||||||
|
value: string;
|
||||||
|
unit: string;
|
||||||
|
count: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SearchData {
|
||||||
|
baseid: string;
|
||||||
|
stnm: string;
|
||||||
|
month: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DetailTabItem {
|
||||||
|
key: string;
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
@ -32,7 +32,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, onUnmounted, watch, computed } from 'vue';
|
import { ref, onUnmounted, watch, computed, nextTick } from 'vue';
|
||||||
import { CloseOutlined } from '@ant-design/icons-vue';
|
import { CloseOutlined } from '@ant-design/icons-vue';
|
||||||
import videojs from 'video.js';
|
import videojs from 'video.js';
|
||||||
import 'video.js/dist/video-js.css';
|
import 'video.js/dist/video-js.css';
|
||||||
@ -279,27 +279,30 @@ const handleClose = () => {
|
|||||||
emit('close', props.videoData?.key);
|
emit('close', props.videoData?.key);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 监听视频URL变化
|
// 监听视频数据变化
|
||||||
watch(
|
watch(
|
||||||
videoUrl,
|
() => props.videoData,
|
||||||
(newUrl, oldUrl) => {
|
(newData, oldData) => {
|
||||||
|
const newUrl = newData?.url;
|
||||||
|
const oldUrl = oldData?.url;
|
||||||
|
|
||||||
if (newUrl && newUrl !== oldUrl) {
|
if (newUrl && newUrl !== oldUrl) {
|
||||||
// URL 变化时延迟初始化,确保 DOM 已更新
|
// URL 变化时重新初始化播放器
|
||||||
setTimeout(() => initPlayer(), 200);
|
nextTick(() => {
|
||||||
|
if (player) {
|
||||||
|
player.dispose();
|
||||||
|
player = null;
|
||||||
|
}
|
||||||
|
initPlayer();
|
||||||
|
});
|
||||||
} else if (newUrl && !oldUrl) {
|
} else if (newUrl && !oldUrl) {
|
||||||
// 首次加载
|
// 首次加载
|
||||||
setTimeout(() => initPlayer(), 100);
|
nextTick(() => initPlayer());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true, deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
if (videoUrl.value) {
|
|
||||||
initPlayer();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
// 清理播放器
|
// 清理播放器
|
||||||
if (player) {
|
if (player) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user