Merge branch 'main' of http://123.132.248.154:10000/gitY/LinYeFangHuo
commit
42d41fe0f1
|
|
@ -16,6 +16,9 @@ enum Api {
|
||||||
AddUploadExcel = '/api/Layer/AddUploadExcel',
|
AddUploadExcel = '/api/Layer/AddUploadExcel',
|
||||||
// 批量更新
|
// 批量更新
|
||||||
UpdateTableOriginalData = '/api/Layer/UpdateTableOriginalData',
|
UpdateTableOriginalData = '/api/Layer/UpdateTableOriginalData',
|
||||||
|
// 列表导入
|
||||||
|
UploadShape = '/api/Layer/UploadShape',
|
||||||
|
UploadExcelAll = '/api/Layer/UploadExcelAll',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GetTableColumnList = ( params: { tableName: string } ) =>
|
export const GetTableColumnList = ( params: { tableName: string } ) =>
|
||||||
|
|
@ -69,3 +72,18 @@ export const UpdateTableOriginalData = (params: {tableName: string, list: Object
|
||||||
url: Api.UpdateTableOriginalData,
|
url: Api.UpdateTableOriginalData,
|
||||||
data: params
|
data: params
|
||||||
})
|
})
|
||||||
|
export const UploadShape = (params: {zipFilePath: string, tableName: string}) =>
|
||||||
|
defHttp.post({
|
||||||
|
url: Api.UploadShape,
|
||||||
|
params,
|
||||||
|
data: params
|
||||||
|
})
|
||||||
|
export const UploadExcelAll = (params: {File: FormData, tableName: string}) =>
|
||||||
|
defHttp.post({
|
||||||
|
url: Api.UploadExcelAll,
|
||||||
|
params: {tableName: params.tableName},
|
||||||
|
data: params.File,
|
||||||
|
headers: {
|
||||||
|
'Content-type': 'multipart/form-data',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
@ -15,7 +15,12 @@
|
||||||
{
|
{
|
||||||
"title":"费县马庄镇陈家鱼后村南斜坡后村",
|
"title":"费县马庄镇陈家鱼后村南斜坡后村",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title":"可落",
|
||||||
|
"videourl": "8H03AA1PAG8D9BF",
|
||||||
|
"manufacturer": "乐橙"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -127,8 +127,26 @@
|
||||||
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
||||||
/>
|
/>
|
||||||
<PlayVideo
|
<MonitorHK
|
||||||
v-if="!isEdit && videoItem.videourl && !videoItem.manufacturer"
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '海康'"
|
||||||
|
:index="index + '-' + videoIndex"
|
||||||
|
:serialNumberValue="videoItem.videourl"
|
||||||
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
/>
|
||||||
|
<MonitorLC
|
||||||
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '乐橙'"
|
||||||
|
:deviceId="videoItem.videourl"
|
||||||
|
:channelId="0"
|
||||||
|
:index="index + '-' + videoIndex"
|
||||||
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
|
/>
|
||||||
|
<MonitorTX
|
||||||
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '腾讯'"
|
||||||
:videourl="videoItem.videourl"
|
:videourl="videoItem.videourl"
|
||||||
:index="index + '-' + videoIndex"
|
:index="index + '-' + videoIndex"
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
|
@ -138,14 +156,6 @@
|
||||||
:videoMuted="option.dataStyle.videoMuted"
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
:videoFit="option.dataStyle.videoFit"
|
:videoFit="option.dataStyle.videoFit"
|
||||||
/>
|
/>
|
||||||
<MulHKmonitor
|
|
||||||
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '海康'"
|
|
||||||
:index="index + '-' + videoIndex"
|
|
||||||
:serialNumberValue="videoItem.videourl"
|
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
|
||||||
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
|
||||||
:timestamp="option.dataStyle.timestamp"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 单个 -->
|
<!-- 单个 -->
|
||||||
|
|
@ -161,8 +171,26 @@
|
||||||
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
||||||
/>
|
/>
|
||||||
<PlayVideo
|
<MonitorHK
|
||||||
v-if="!isEdit && item.videos.videourl && !item.videos.manufacturer"
|
v-if="!isEdit && item.videos.videourl && item.videos.manufacturer == '海康'"
|
||||||
|
:index="index + '-' + videoIndex"
|
||||||
|
:serialNumberValue="item.videos.videourl"
|
||||||
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
/>
|
||||||
|
<MonitorLC
|
||||||
|
v-if="!isEdit && item.videos.videourl && item.videos.manufacturer == '乐橙'"
|
||||||
|
:deviceId="item.videos.videourl"
|
||||||
|
:channelId="0"
|
||||||
|
:index="index"
|
||||||
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
|
/>
|
||||||
|
<MonitorTX
|
||||||
|
v-if="!isEdit && item.videos.videourl && item.videos.manufacturer == '腾讯'"
|
||||||
:videourl="item.videos.videourl"
|
:videourl="item.videos.videourl"
|
||||||
:index="index + '-0'"
|
:index="index + '-0'"
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
|
@ -172,14 +200,6 @@
|
||||||
:videoMuted="option.dataStyle.videoMuted"
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
:videoFit="option.dataStyle.videoFit"
|
:videoFit="option.dataStyle.videoFit"
|
||||||
/>
|
/>
|
||||||
<MulHKmonitor
|
|
||||||
v-if="!isEdit && item.videos.videourl && item.videos.manufacturer == '海康'"
|
|
||||||
:index="index + '-' + videoIndex"
|
|
||||||
:serialNumberValue="item.videos.videourl"
|
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
|
||||||
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
|
||||||
:timestamp="option.dataStyle.timestamp"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -198,7 +218,7 @@
|
||||||
import { replaceSqlParams } from '@/utils/sqlHandler';
|
import { replaceSqlParams } from '@/utils/sqlHandler';
|
||||||
import Title from './svg/title.vue';
|
import Title from './svg/title.vue';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { MulHKmonitor, PlayVideo } from './video/index';
|
import { MonitorHK, MonitorLC, MonitorTX } from './video/index';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
chartConfig: {
|
chartConfig: {
|
||||||
|
|
@ -311,7 +331,7 @@
|
||||||
|
|
||||||
.timeLineVideoDivTitle {
|
.timeLineVideoDivTitle {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 10;
|
z-index: 100;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
left: 5px;
|
left: 5px;
|
||||||
font-size: v-bind('`${option.dataStyle.videoTitleFontSize}px`');
|
font-size: v-bind('`${option.dataStyle.videoTitleFontSize}px`');
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import MulHKmonitor from './mulHKmonitor.vue';
|
import MonitorHK from './monitorHK.vue';
|
||||||
import PlayVideo from './playVideo.vue';
|
import MonitorLC from './monitorLC.vue';
|
||||||
|
import MonitorTX from './monitorTX.vue';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
MulHKmonitor,
|
MonitorHK,
|
||||||
PlayVideo,
|
MonitorLC,
|
||||||
|
MonitorTX,
|
||||||
};
|
};
|
||||||
|
|
@ -0,0 +1,208 @@
|
||||||
|
<template>
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-container">
|
||||||
|
<div :id="'root' + props.index + props.timestamp"></div>
|
||||||
|
</div>
|
||||||
|
<div class="box-controls">
|
||||||
|
<div class="left-controls">
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="playOrPauseClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<Pause
|
||||||
|
v-if="control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<CaretForward
|
||||||
|
v-if="!control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="volumeClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<VolumeHigh
|
||||||
|
v-if="!control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<VolumeMute
|
||||||
|
v-if="control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="right-controls">
|
||||||
|
<n-button quaternary @click="fullScreenClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<ExpandOutlined
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, onUnmounted, watch, ref } from 'vue';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { ExpandOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { Pause, CaretForward, VolumeHigh, VolumeMute } from '@vicons/ionicons5';
|
||||||
|
|
||||||
|
let BASE_URL = 'http://111.17.207.220:9001/api';
|
||||||
|
|
||||||
|
const props = defineProps([
|
||||||
|
'deviceId',
|
||||||
|
'channelId',
|
||||||
|
'index',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'timestamp',
|
||||||
|
'videoMuted',
|
||||||
|
]);
|
||||||
|
let clPlayer: any = null;
|
||||||
|
|
||||||
|
// 开始播放/暂停播放
|
||||||
|
const control_playOrPause = ref(true);
|
||||||
|
// 音量:true为静音
|
||||||
|
const control_volume = ref(true);
|
||||||
|
// 全屏
|
||||||
|
const control_fullScreen = ref(false);
|
||||||
|
|
||||||
|
// 开始播放/暂停播放方法
|
||||||
|
function playOrPauseClick() {
|
||||||
|
control_playOrPause.value = !control_playOrPause.value;
|
||||||
|
if (control_playOrPause.value) {
|
||||||
|
clPlayer.play();
|
||||||
|
} else {
|
||||||
|
clPlayer.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 音量
|
||||||
|
function volumeClick() {
|
||||||
|
control_volume.value = !control_volume.value;
|
||||||
|
if (control_volume.value) {
|
||||||
|
clPlayer.volume(0);
|
||||||
|
} else {
|
||||||
|
clPlayer.volume(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全屏
|
||||||
|
function fullScreenClick() {
|
||||||
|
clPlayer.fullScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取kitToken
|
||||||
|
function getKitToken(deviceId, channelId) {
|
||||||
|
axios({
|
||||||
|
method: 'post',
|
||||||
|
url: BASE_URL + '/Camera/getKitToken?deviceId=' + deviceId + '&channelId=0' + '&type=0',
|
||||||
|
}).then((res) => {
|
||||||
|
let kitToken = res.data.result.data.kitToken;
|
||||||
|
loadMonitorVideo(deviceId, kitToken, channelId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始
|
||||||
|
function loadMonitorVideo(deviceId, kitToken, channelId) {
|
||||||
|
// 结束上一个
|
||||||
|
closeMonitorVideo();
|
||||||
|
|
||||||
|
clPlayer = new imouPlayer({
|
||||||
|
id: 'root' + props.index + props.timestamp,
|
||||||
|
width: props.width,
|
||||||
|
height: props.height - 25,
|
||||||
|
deviceId: deviceId,
|
||||||
|
token: kitToken,
|
||||||
|
channelId: channelId,
|
||||||
|
type: 1,
|
||||||
|
streamId: 0,
|
||||||
|
recordType: 'cloud',
|
||||||
|
code: '',
|
||||||
|
controls: true,
|
||||||
|
});
|
||||||
|
clPlayer.volume(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 结束
|
||||||
|
function closeMonitorVideo() {
|
||||||
|
if (clPlayer != null) {
|
||||||
|
clPlayer.destroy();
|
||||||
|
clPlayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.deviceId,
|
||||||
|
() => {
|
||||||
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
control_volume.value = props.videoMuted;
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
closeMonitorVideo();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.box {
|
||||||
|
width: v-bind('`${props.width}px`');
|
||||||
|
height: v-bind('`${props.height}px`');
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
.box-container {
|
||||||
|
width: v-bind('`${props.width}px`');
|
||||||
|
height: v-bind('`${props.height-25}px`');
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-controls {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
align-items: center;
|
||||||
|
background: #000000;
|
||||||
|
height: 25px;
|
||||||
|
width: 100%;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-controls {
|
||||||
|
display: flex;
|
||||||
|
justify-self: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-controls {
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<n-select
|
<n-select
|
||||||
v-model:value="optionData.dataStyle.serialNumberValue"
|
v-model:value="optionData.dataStyle.serialNumberValue"
|
||||||
:options="option.dataset"
|
:options="option.dataset"
|
||||||
label-field="name"
|
label-field="title"
|
||||||
value-field="serialNumber"
|
value-field="serialNumber"
|
||||||
placeholder="请选择默认视频"
|
placeholder="请选择默认视频"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -2,73 +2,79 @@
|
||||||
"source": [
|
"source": [
|
||||||
{
|
{
|
||||||
"id": 418015298064389,
|
"id": 418015298064389,
|
||||||
"name": "XZD148青山裕南山",
|
"title": "XZD148青山裕南山",
|
||||||
"serialNumber": "13b23c9b878143bc99269898964af54f",
|
"serialNumber": "13b23c9b878143bc99269898964af54f",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015349661701,
|
"id": 418015349661701,
|
||||||
"name": "XZD153狼窝沟西南",
|
"title": "XZD153狼窝沟西南",
|
||||||
"serialNumber": "74b95e6575d741489b9a9061bb646467",
|
"serialNumber": "74b95e6575d741489b9a9061bb646467",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015349899269,
|
"id": 418015349899269,
|
||||||
"name": "XZD152青山裕水库东",
|
"title": "XZD152青山裕水库东",
|
||||||
"serialNumber": "ecdb49050c57452dbae7ec6f03e82667",
|
"serialNumber": "ecdb49050c57452dbae7ec6f03e82667",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015350452229,
|
"id": 418015350452229,
|
||||||
"name": "XZD147大古台南山",
|
"title": "XZD147大古台南山",
|
||||||
"serialNumber": "edd84ccac34441c48c6a7bf030f9c13f",
|
"serialNumber": "edd84ccac34441c48c6a7bf030f9c13f",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015351681029,
|
"id": 418015351681029,
|
||||||
"name": "XZD151青山裕水库西",
|
"title": "XZD151青山裕水库西",
|
||||||
"serialNumber": "c10f9faea87d4f659e2bc01de24e29a9",
|
"serialNumber": "c10f9faea87d4f659e2bc01de24e29a9",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015351836677,
|
"id": 418015351836677,
|
||||||
"name": "XZD149青山裕北山",
|
"title": "XZD149青山裕北山",
|
||||||
"serialNumber": "909e98d192f649fea4c5269f5f7832e1",
|
"serialNumber": "909e98d192f649fea4c5269f5f7832e1",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015351025669,
|
"id": 418015351025669,
|
||||||
"name": "XZD150青山裕山里人家西北",
|
"title": "XZD150青山裕山里人家西北",
|
||||||
"serialNumber": "b56f09f8c64249379e42481c7b173dce",
|
"serialNumber": "b56f09f8c64249379e42481c7b173dce",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 490483936976901,
|
"id": 490483936976901,
|
||||||
"name": "XZD155突围路广场",
|
"title": "XZD155突围路广场",
|
||||||
"serialNumber": "a8010ac49baa4b81a569ba24dc95a4e7",
|
"serialNumber": "a8010ac49baa4b81a569ba24dc95a4e7",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 490483936976911,
|
"id": 490483936976911,
|
||||||
"name": "playerVideo",
|
"title": "大青山林场机库摄像头",
|
||||||
|
"serialNumber": "http://111.36.45.20:18000/flv/hls/H-fc4c09b5a3451bb9.flv",
|
||||||
|
"manufacturer": "腾讯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 490483936976911,
|
||||||
|
"title": "玉皇宫机库摄像头",
|
||||||
"serialNumber": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"serialNumber": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 490483936976912,
|
"id": 490483936976912,
|
||||||
"name": "店子分区",
|
"title": "店子分区",
|
||||||
"serialNumber": "8H03AA1PAGDC8C3",
|
"serialNumber": "8H03AA1PAGDC8C3",
|
||||||
"manufacturer": "乐橙"
|
"manufacturer": "乐橙"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 490483936976913,
|
"id": 490483936976913,
|
||||||
"name": "白马关通天沟",
|
"title": "白马关通天沟",
|
||||||
"serialNumber": "8H03AA1PAG97234",
|
"serialNumber": "8H03AA1PAG97234",
|
||||||
"manufacturer": "乐橙"
|
"manufacturer": "乐橙"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 490483936976914,
|
"id": 490483936976914,
|
||||||
"name": "后白崖",
|
"title": "后白崖",
|
||||||
"serialNumber": "8H03AA1PAGF203B",
|
"serialNumber": "8H03AA1PAGF203B",
|
||||||
"manufacturer": "乐橙"
|
"manufacturer": "乐橙"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<n-button>
|
<n-button>
|
||||||
<span
|
<span
|
||||||
calss="modalTitle_name"
|
calss="modalTitle_title"
|
||||||
:style="{
|
:style="{
|
||||||
color: option.dataStyle.titleFontColor,
|
color: option.dataStyle.titleFontColor,
|
||||||
fontSize: option.dataStyle.titleFontSize + 'px',
|
fontSize: option.dataStyle.titleFontSize + 'px',
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
<n-select
|
<n-select
|
||||||
v-model:value="option.dataStyle.serialNumberValue"
|
v-model:value="option.dataStyle.serialNumberValue"
|
||||||
:options="option.dataset"
|
:options="option.dataset"
|
||||||
label-field="name"
|
label-field="title"
|
||||||
value-field="serialNumber"
|
value-field="serialNumber"
|
||||||
placeholder="请选择查看的视频"
|
placeholder="请选择查看的视频"
|
||||||
/>
|
/>
|
||||||
|
|
@ -49,10 +49,11 @@
|
||||||
:width="`${w - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
|
:width="`${w - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
|
||||||
:height="`${h - option.dataStyle.modalTitleHeight - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
|
:height="`${h - option.dataStyle.modalTitleHeight - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
|
||||||
:timestamp="option.dataStyle.timestamp"
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
/>
|
/>
|
||||||
<PlayVideo
|
<MonitorTX
|
||||||
ref="PlayVideoRef"
|
ref="MonitorTXRef"
|
||||||
v-if="!isEdit && !manufacturer"
|
v-if="!isEdit && manufacturer == '腾讯'"
|
||||||
:serialNumberValue="option.dataStyle.serialNumberValue"
|
:serialNumberValue="option.dataStyle.serialNumberValue"
|
||||||
:width="`${w - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
|
:width="`${w - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
|
||||||
:height="`${h - option.dataStyle.modalTitleHeight - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
|
:height="`${h - option.dataStyle.modalTitleHeight - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
|
||||||
|
|
@ -84,7 +85,7 @@
|
||||||
import { EventBus } from '@/utils/eventBus';
|
import { EventBus } from '@/utils/eventBus';
|
||||||
import { replaceSqlParams } from '@/utils/sqlHandler';
|
import { replaceSqlParams } from '@/utils/sqlHandler';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { MonitorHK, MonitorLC, PlayVideo } from './video/index';
|
import { MonitorHK, MonitorLC, MonitorTX } from './video/index';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
chartConfig: {
|
chartConfig: {
|
||||||
|
|
@ -107,8 +108,8 @@
|
||||||
const MonitorHKRef = ref();
|
const MonitorHKRef = ref();
|
||||||
// 乐橙
|
// 乐橙
|
||||||
const MonitorLCRef = ref();
|
const MonitorLCRef = ref();
|
||||||
// 其他
|
// 腾讯
|
||||||
const PlayVideoRef = ref();
|
const MonitorTXRef = ref();
|
||||||
|
|
||||||
// 是否是编辑状态
|
// 是否是编辑状态
|
||||||
const isEdit = window.location.href.includes('/chart/home/');
|
const isEdit = window.location.href.includes('/chart/home/');
|
||||||
|
|
@ -136,7 +137,7 @@
|
||||||
() => option.dataStyle.serialNumberValue,
|
() => option.dataStyle.serialNumberValue,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
let data = getDataBySerialNumberValue(newValue);
|
let data = getDataBySerialNumberValue(newValue);
|
||||||
titleName.value = data.name;
|
titleName.value = data.title;
|
||||||
manufacturer.value = data.manufacturer;
|
manufacturer.value = data.manufacturer;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -157,7 +158,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = getDataBySerialNumberValue(option.dataStyle.serialNumberValue);
|
let data = getDataBySerialNumberValue(option.dataStyle.serialNumberValue);
|
||||||
titleName.value = data.name;
|
titleName.value = data.title;
|
||||||
manufacturer.value = data.manufacturer;
|
manufacturer.value = data.manufacturer;
|
||||||
|
|
||||||
// 组件通信
|
// 组件通信
|
||||||
|
|
@ -208,7 +209,7 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
|
|
||||||
.modalTitle_name {
|
.modalTitle_title {
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: v-bind('`${option.dataStyle.modalTitleHeight}px`');
|
height: v-bind('`${option.dataStyle.modalTitleHeight}px`');
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import MonitorHK from './monitorHK.vue';
|
import MonitorHK from './monitorHK.vue';
|
||||||
import MonitorLC from './monitorLC.vue';
|
import MonitorLC from './monitorLC.vue';
|
||||||
import PlayVideo from './playVideo.vue';
|
import MonitorTX from './monitorTX.vue';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
MonitorHK,
|
MonitorHK,
|
||||||
MonitorLC,
|
MonitorLC,
|
||||||
PlayVideo,
|
MonitorTX,
|
||||||
};
|
};
|
||||||
|
|
@ -132,24 +132,9 @@
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
.then(function (oData) {
|
.then(function (oData) {
|
||||||
// 实际宽高
|
// 重定大小
|
||||||
let width = props.width;
|
reSizeVideo();
|
||||||
let height = props.height;
|
|
||||||
const divElement = document.getElementById('camera-box');
|
|
||||||
if (divElement) {
|
|
||||||
const rect = divElement.getBoundingClientRect();
|
|
||||||
const rectWidth = rect.width;
|
|
||||||
const rectHeight = rect.height;
|
|
||||||
if (rectWidth < width) {
|
|
||||||
width = rectWidth;
|
|
||||||
}
|
|
||||||
if (rectHeight < height) {
|
|
||||||
height = rectHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
oWebControl.JS_Resize(width, height); // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 开始预览多个视频
|
// 开始预览多个视频
|
||||||
oWebControl.JS_RequestInterface({
|
oWebControl.JS_RequestInterface({
|
||||||
funcName: 'startPreview',
|
funcName: 'startPreview',
|
||||||
|
|
@ -176,6 +161,26 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 重定大小
|
||||||
|
function reSizeVideo() {
|
||||||
|
// 实际宽高
|
||||||
|
let width = props.width;
|
||||||
|
let height = props.height;
|
||||||
|
const divElement = document.getElementById('camera-box');
|
||||||
|
if (divElement) {
|
||||||
|
const rect = divElement.getBoundingClientRect();
|
||||||
|
const rectWidth = rect.width;
|
||||||
|
const rectHeight = rect.height;
|
||||||
|
if (rectWidth < width) {
|
||||||
|
width = rectWidth;
|
||||||
|
}
|
||||||
|
if (rectHeight < height) {
|
||||||
|
height = rectHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oWebControl.JS_Resize(width, height); // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.serialNumberValue,
|
() => props.serialNumberValue,
|
||||||
() => {
|
() => {
|
||||||
|
|
@ -212,10 +217,28 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
// 启动视频窗口
|
||||||
initPlugin();
|
initPlugin();
|
||||||
|
// 添加监听滚动事件
|
||||||
|
const elements = document.querySelectorAll('.ZhiGan_ModalVideo');
|
||||||
|
if (elements.length > 0) {
|
||||||
|
// 遍历每个元素并绑定 scroll 事件
|
||||||
|
elements.forEach((element) => {
|
||||||
|
element.addEventListener('scroll', reSizeVideo);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
// 销毁视频窗口
|
||||||
closeHkVideo();
|
closeHkVideo();
|
||||||
|
// 移除监听滚动事件
|
||||||
|
const elements = document.querySelectorAll('.ZhiGan_ModalVideo');
|
||||||
|
if (elements.length > 0) {
|
||||||
|
// 遍历每个元素并绑定 scroll 事件
|
||||||
|
elements.forEach((element) => {
|
||||||
|
element.removeEventListener('scroll', reSizeVideo);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|
|
||||||
|
|
@ -1,92 +1,66 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-container">
|
<div class="box-container">
|
||||||
<div id="root"></div>
|
<div :id="'root' + props.timestamp"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-controls">
|
<div class="box-controls">
|
||||||
|
<div class="left-controls">
|
||||||
<div>
|
<div>
|
||||||
<n-button quaternary @click="playOrPauseClick">
|
<n-button quaternary @click="playOrPauseClick">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<n-icon>
|
<n-icon>
|
||||||
<svg
|
<Pause
|
||||||
v-if="control_playOrPause"
|
v-if="control_playOrPause"
|
||||||
version="1.1"
|
:style="{
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
fontSize: '20px',
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
color: '#ffffff',
|
||||||
x="0px"
|
}"
|
||||||
y="0px"
|
/>
|
||||||
viewBox="0 0 512 512"
|
<CaretForward
|
||||||
enable-background="new 0 0 512 512"
|
|
||||||
xml:space="preserve"
|
|
||||||
>
|
|
||||||
<path d="M96,448h106.7V64H96V448z M309.3,64v384H416V64H309.3z"></path>
|
|
||||||
</svg>
|
|
||||||
<svg
|
|
||||||
v-if="!control_playOrPause"
|
v-if="!control_playOrPause"
|
||||||
version="1.1"
|
:style="{
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
fontSize: '20px',
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
color: '#ffffff',
|
||||||
x="0px"
|
}"
|
||||||
y="0px"
|
/>
|
||||||
viewBox="0 0 512 512"
|
|
||||||
enable-background="new 0 0 512 512"
|
|
||||||
xml:space="preserve"
|
|
||||||
>
|
|
||||||
<path d="M96,52v408l320-204L96,52z"></path>
|
|
||||||
</svg>
|
|
||||||
</n-icon>
|
</n-icon>
|
||||||
</template>
|
</template>
|
||||||
</n-button>
|
</n-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<n-button quaternary @click="volumeClick">
|
<n-button quaternary @click="volumeClick">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<n-icon>
|
<n-icon>
|
||||||
<svg
|
<VolumeHigh
|
||||||
v-if="control_volume"
|
|
||||||
version="1.1"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
x="0px"
|
|
||||||
y="0px"
|
|
||||||
viewBox="0 0 512 512"
|
|
||||||
enable-background="new 0 0 512 512"
|
|
||||||
xml:space="preserve"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M64,192v128h85.334L256,431.543V80.458L149.334,192H64z M352,256c0-38.399-21.333-72.407-53.333-88.863v176.636
|
|
||||||
C330.667,328.408,352,294.4,352,256z M298.667,64v44.978C360.531,127.632,405.334,186.882,405.334,256
|
|
||||||
c0,69.119-44.803,128.369-106.667,147.022V448C384,428.254,448,349.257,448,256C448,162.744,384,83.746,298.667,64z"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
<svg
|
|
||||||
v-if="!control_volume"
|
v-if="!control_volume"
|
||||||
version="1.1"
|
:style="{
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
fontSize: '20px',
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
color: '#ffffff',
|
||||||
x="0px"
|
}"
|
||||||
y="0px"
|
/>
|
||||||
viewBox="0 0 512 512"
|
<VolumeMute
|
||||||
enable-background="new 0 0 512 512"
|
v-if="control_volume"
|
||||||
xml:space="preserve"
|
:style="{
|
||||||
>
|
fontSize: '20px',
|
||||||
<g>
|
color: '#ffffff',
|
||||||
<path
|
}"
|
||||||
d="M405.5,256c0,22.717-4.883,44.362-13.603,63.855l31.88,31.88C439.283,323.33,448,290.653,448,256
|
/>
|
||||||
c0-93.256-64-172.254-149-192v44.978C361,127.632,405.5,186.882,405.5,256z"
|
</n-icon>
|
||||||
></path>
|
</template>
|
||||||
<polygon points="256,80.458 204.979,132.938 256,183.957 "></polygon>
|
</n-button>
|
||||||
<path
|
</div>
|
||||||
d="M420.842,396.885L91.116,67.157l-24,24l90.499,90.413l-8.28,10.43H64v128h85.334L256,431.543V280l94.915,94.686
|
</div>
|
||||||
C335.795,387.443,318,397.213,299,403.022V448c31-7.172,58.996-22.163,82.315-42.809l39.61,39.693l24-24.043l-24.002-24.039
|
|
||||||
L420.842,396.885z"
|
<div class="right-controls">
|
||||||
></path>
|
<n-button quaternary @click="fullScreenClick">
|
||||||
<path
|
<template #icon>
|
||||||
d="M352.188,256c0-38.399-21.188-72.407-53.188-88.863v59.82l50.801,50.801C351.355,270.739,352.188,263.454,352.188,256z"
|
<n-icon>
|
||||||
></path>
|
<ExpandOutlined
|
||||||
</g>
|
:style="{
|
||||||
</svg>
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
</n-icon>
|
</n-icon>
|
||||||
</template>
|
</template>
|
||||||
</n-button>
|
</n-button>
|
||||||
|
|
@ -97,18 +71,52 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, onUnmounted, watch, ref } from 'vue';
|
import { onMounted, onUnmounted, watch, ref } from 'vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import { ExpandOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { Pause, CaretForward, VolumeHigh, VolumeMute } from '@vicons/ionicons5';
|
||||||
|
|
||||||
let BASE_URL = 'http://111.17.207.220:9001/api';
|
let BASE_URL = 'http://111.17.207.220:9001/api';
|
||||||
|
|
||||||
const props = defineProps(['deviceId', 'channelId', 'width', 'height', 'timestamp']);
|
const props = defineProps([
|
||||||
|
'deviceId',
|
||||||
|
'channelId',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'timestamp',
|
||||||
|
'videoMuted',
|
||||||
|
]);
|
||||||
let clPlayer: any = null;
|
let clPlayer: any = null;
|
||||||
|
|
||||||
// 开始播放/暂停播放
|
// 开始播放/暂停播放
|
||||||
const control_playOrPause = ref(true);
|
const control_playOrPause = ref(true);
|
||||||
// 音量
|
// 音量:true为静音
|
||||||
const control_volume = ref(true);
|
const control_volume = ref(true);
|
||||||
// 全屏
|
// 全屏
|
||||||
const control_fullScreen = ref(true);
|
const control_fullScreen = ref(false);
|
||||||
|
|
||||||
|
// 开始播放/暂停播放方法
|
||||||
|
function playOrPauseClick() {
|
||||||
|
control_playOrPause.value = !control_playOrPause.value;
|
||||||
|
if (control_playOrPause.value) {
|
||||||
|
clPlayer.play();
|
||||||
|
} else {
|
||||||
|
clPlayer.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 音量
|
||||||
|
function volumeClick() {
|
||||||
|
control_volume.value = !control_volume.value;
|
||||||
|
if (control_volume.value) {
|
||||||
|
clPlayer.volume(0);
|
||||||
|
} else {
|
||||||
|
clPlayer.volume(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全屏
|
||||||
|
function fullScreenClick() {
|
||||||
|
clPlayer.fullScreen();
|
||||||
|
}
|
||||||
|
|
||||||
// 获取kitToken
|
// 获取kitToken
|
||||||
function getKitToken(deviceId, channelId) {
|
function getKitToken(deviceId, channelId) {
|
||||||
|
|
@ -126,10 +134,10 @@
|
||||||
// 结束上一个
|
// 结束上一个
|
||||||
closeMonitorVideo();
|
closeMonitorVideo();
|
||||||
|
|
||||||
clPlayer = new window.imouPlayer({
|
clPlayer = new imouPlayer({
|
||||||
id: 'root',
|
id: 'root' + props.timestamp,
|
||||||
width: props.width,
|
width: props.width,
|
||||||
height: props.height,
|
height: props.height - 35,
|
||||||
deviceId: deviceId,
|
deviceId: deviceId,
|
||||||
token: kitToken,
|
token: kitToken,
|
||||||
channelId: channelId,
|
channelId: channelId,
|
||||||
|
|
@ -139,6 +147,7 @@
|
||||||
code: '',
|
code: '',
|
||||||
controls: true,
|
controls: true,
|
||||||
});
|
});
|
||||||
|
clPlayer.volume(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 结束
|
// 结束
|
||||||
|
|
@ -158,6 +167,7 @@
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getKitToken(props.deviceId, props.channelId);
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
control_volume.value = props.videoMuted;
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
|
@ -170,22 +180,28 @@
|
||||||
width: v-bind('`${props.width}px`');
|
width: v-bind('`${props.width}px`');
|
||||||
height: v-bind('`${props.height}px`');
|
height: v-bind('`${props.height}px`');
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
.box-container {
|
.box-container {
|
||||||
width: v-bind('`${props.width}px`');
|
width: v-bind('`${props.width}px`');
|
||||||
height: v-bind('`${props.height}px`');
|
height: v-bind('`${props.height-35}px`');
|
||||||
}
|
}
|
||||||
|
|
||||||
.box-controls {
|
.box-controls {
|
||||||
position: absolute;
|
display: grid;
|
||||||
left: 0px;
|
grid-template-columns: auto 1fr;
|
||||||
bottom: 0px;
|
align-items: center;
|
||||||
display: inline-flex;
|
background: #000000;
|
||||||
background: #ffffff00;
|
|
||||||
height: 35px;
|
height: 35px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 100;
|
gap: 10px;
|
||||||
border: 1px solid red;
|
}
|
||||||
|
|
||||||
|
.left-controls {
|
||||||
|
display: flex;
|
||||||
|
justify-self: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-controls {
|
||||||
|
justify-self: end;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,22 @@
|
||||||
<template>
|
<template>
|
||||||
|
<div>
|
||||||
<video
|
<video
|
||||||
:id="'ZhiGan_ModalVideo' + props.timestamp"
|
:id="'ZhiGan_ModalVideo' + props.timestamp"
|
||||||
class="TCPlayer-video-contaiiner"
|
class="TCPlayer-video-container"
|
||||||
preload="auto"
|
preload="auto"
|
||||||
crossOrigin="anonymous"
|
crossOrigin="anonymous"
|
||||||
playsinline
|
playsinline
|
||||||
autoplay
|
autoplay
|
||||||
:loop="props.videoLoop"
|
:loop="props.videoLoop"
|
||||||
:muted="props.videoMuted"
|
:muted="props.videoMuted"
|
||||||
:width="props.width"
|
:style="{
|
||||||
:height="props.height"
|
width: props.width + 'px',
|
||||||
|
height: props.height + 'px',
|
||||||
|
}"
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, onUnmounted, ref, watch, nextTick } from 'vue';
|
import { onMounted, onUnmounted, ref, watch, nextTick } from 'vue';
|
||||||
|
|
||||||
|
|
@ -29,14 +34,14 @@
|
||||||
let player: any = null;
|
let player: any = null;
|
||||||
|
|
||||||
function handlerPlayVideo() {
|
function handlerPlayVideo() {
|
||||||
setTimeout(function () {
|
nextTick(() => {
|
||||||
if (player) {
|
if (player) {
|
||||||
player.src(props.serialNumberValue);
|
player.src(props.serialNumberValue);
|
||||||
} else {
|
} else {
|
||||||
player = TCPlayer('ZhiGan_ModalVideo' + props.timestamp, {});
|
player = TCPlayer('ZhiGan_ModalVideo' + props.timestamp, {});
|
||||||
player.src(props.serialNumberValue);
|
player.src(props.serialNumberValue);
|
||||||
}
|
}
|
||||||
}, 1000);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function closePlayerVideo() {
|
function closePlayerVideo() {
|
||||||
|
|
@ -56,6 +61,7 @@
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
handlerPlayVideo();
|
handlerPlayVideo();
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
closePlayerVideo();
|
closePlayerVideo();
|
||||||
});
|
});
|
||||||
|
|
@ -65,6 +71,7 @@
|
||||||
closePlayerVideo,
|
closePlayerVideo,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
video {
|
video {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
@ -68,10 +68,10 @@ export const option = {
|
||||||
videoWidth: 956,
|
videoWidth: 956,
|
||||||
videoHeight: 688,
|
videoHeight: 688,
|
||||||
// 关闭按钮
|
// 关闭按钮
|
||||||
closeVideoIconColor: '#027734',
|
closeVideoIconColor: '#ffffff',
|
||||||
closeVideoIconWidthAndHeight: 34,
|
closeVideoIconWidthAndHeight: 25,
|
||||||
// 标题
|
// 标题
|
||||||
videoTitleFontSize: 16,
|
videoTitleFontSize: 20,
|
||||||
videoTitleFontColor: '#ffffff',
|
videoTitleFontColor: '#ffffff',
|
||||||
|
|
||||||
videoloop: false, // 视频-循环播放
|
videoloop: false, // 视频-循环播放
|
||||||
|
|
|
||||||
|
|
@ -4,49 +4,41 @@
|
||||||
"label": "费县林业防火监控列表",
|
"label": "费县林业防火监控列表",
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"id": 418015298064389,
|
|
||||||
"title": "XZD148青山裕南山",
|
"title": "XZD148青山裕南山",
|
||||||
"videourl": "13b23c9b878143bc99269898964af54f",
|
"videourl": "13b23c9b878143bc99269898964af54f",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015349661701,
|
|
||||||
"title": "XZD153狼窝沟西南",
|
"title": "XZD153狼窝沟西南",
|
||||||
"videourl": "74b95e6575d741489b9a9061bb646467",
|
"videourl": "74b95e6575d741489b9a9061bb646467",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015349899269,
|
|
||||||
"title": "XZD152青山裕水库东",
|
"title": "XZD152青山裕水库东",
|
||||||
"videourl": "ecdb49050c57452dbae7ec6f03e82667",
|
"videourl": "ecdb49050c57452dbae7ec6f03e82667",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015350452229,
|
|
||||||
"title": "XZD147大古台南山",
|
"title": "XZD147大古台南山",
|
||||||
"videourl": "edd84ccac34441c48c6a7bf030f9c13f",
|
"videourl": "edd84ccac34441c48c6a7bf030f9c13f",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015351681029,
|
|
||||||
"title": "XZD151青山裕水库西",
|
"title": "XZD151青山裕水库西",
|
||||||
"videourl": "c10f9faea87d4f659e2bc01de24e29a9",
|
"videourl": "c10f9faea87d4f659e2bc01de24e29a9",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015351836677,
|
|
||||||
"title": "XZD149青山裕北山",
|
"title": "XZD149青山裕北山",
|
||||||
"videourl": "909e98d192f649fea4c5269f5f7832e1",
|
"videourl": "909e98d192f649fea4c5269f5f7832e1",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015351025669,
|
|
||||||
"title": "XZD150青山裕山里人家西北",
|
"title": "XZD150青山裕山里人家西北",
|
||||||
"videourl": "b56f09f8c64249379e42481c7b173dce",
|
"videourl": "b56f09f8c64249379e42481c7b173dce",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 490483936976901,
|
|
||||||
"title": "XZD155突围路广场",
|
"title": "XZD155突围路广场",
|
||||||
"videourl": "a8010ac49baa4b81a569ba24dc95a4e7",
|
"videourl": "a8010ac49baa4b81a569ba24dc95a4e7",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
|
|
@ -54,42 +46,47 @@
|
||||||
{
|
{
|
||||||
"title":"费县马庄镇陈家鱼后村南斜坡后村",
|
"title":"费县马庄镇陈家鱼后村南斜坡后村",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"费县东蒙镇天蒙景区二村东边南斜坡后村",
|
"title":"费县东蒙镇天蒙景区二村东边南斜坡后村",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"费县东蒙镇沂蒙抽水蓄能业营地",
|
"title":"费县东蒙镇沂蒙抽水蓄能业营地",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"费县薛庄镇火山后村南斜坡后村",
|
"title":"费县薛庄镇火山后村南斜坡后村",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"费县冯庄镇陈家鱼后村南斜坡后村",
|
"title":"费县冯庄镇陈家鱼后村南斜坡后村",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
|
||||||
{
|
|
||||||
"title":"费县东蒙镇天蒙景区二村东边南斜坡后村",
|
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
|
||||||
"manufacturer": ""
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"费县冻蒙镇沂蒙抽水蓄能业营地",
|
"title":"费县冻蒙镇沂蒙抽水蓄能业营地",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"费县薛庄镇火山后村南斜坡后村",
|
"title": "店子分区",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "8H03AA1PAGDC8C3",
|
||||||
"manufacturer": ""
|
"manufacturer": "乐橙"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "白马关通天沟",
|
||||||
|
"videourl": "8H03AA1PAG97234",
|
||||||
|
"manufacturer": "乐橙"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "后白崖",
|
||||||
|
"videourl": "8H03AA1PAGF203B",
|
||||||
|
"manufacturer": "乐橙"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@
|
||||||
v-for="(videoItem, videoIndex) in option.videoList"
|
v-for="(videoItem, videoIndex) in option.videoList"
|
||||||
:key="videoIndex"
|
:key="videoIndex"
|
||||||
>
|
>
|
||||||
<div class="rightVideoItemTitle" v-if="isEdit || videoItem.title">
|
<div class="rightVideoItemTitle" v-if="isEdit">
|
||||||
<span
|
<span
|
||||||
:style="{
|
:style="{
|
||||||
color: option.dataStyle.videoTitleFontColor,
|
color: option.dataStyle.videoTitleFontColor,
|
||||||
|
|
@ -84,15 +84,18 @@
|
||||||
{{ videoItem.title ? videoItem.title : '视频标题' }}
|
{{ videoItem.title ? videoItem.title : '视频标题' }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="rightVideoItemCloseButton" v-if="isEdit || videoItem.videourl">
|
<div class="rightVideoItemCloseButton" v-if="isEdit">
|
||||||
<CloseVideoIcon :dataStyle="option.dataStyle" @click="closeThisVideo(videoIndex)" />
|
<Close
|
||||||
|
:style="{
|
||||||
|
width: option.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
height: option.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
fontSize: option.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
color: option.dataStyle.closeVideoIconColor,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div :class="changeThisNum == videoIndex ? 'rightVideoItemDiv2' : 'rightVideoItemDiv'">
|
||||||
:class="changeThisNum == videoIndex ? 'rightVideoItemDiv2' : 'rightVideoItemDiv'"
|
|
||||||
@click="changeThisVideo(videoIndex)"
|
|
||||||
>
|
|
||||||
<!-- 无视频url的情况 -->
|
|
||||||
<img
|
<img
|
||||||
v-if="isEdit || !videoItem.videourl"
|
v-if="isEdit || !videoItem.videourl"
|
||||||
:width="videoWidthNoPadding"
|
:width="videoWidthNoPadding"
|
||||||
|
|
@ -100,24 +103,42 @@
|
||||||
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
||||||
preview-disabled
|
preview-disabled
|
||||||
/>
|
/>
|
||||||
<MulHKmonitor
|
<MonitorHK
|
||||||
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '海康'"
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '海康'"
|
||||||
:index="videoIndex"
|
:index="videoIndex"
|
||||||
:serialNumberValue="videoItem.videourl"
|
:serialNumberValue="videoItem.videourl"
|
||||||
:width="videoWidthNoPadding"
|
:width="videoWidthNoPadding"
|
||||||
:height="videoHeightNoPadding"
|
:height="videoHeightNoPadding"
|
||||||
:timestamp="option.dataStyle.timestamp"
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
:dataStyle="option.dataStyle"
|
||||||
|
@changeThisVideo="changeThisVideo"
|
||||||
|
@closeThisVideo="closeThisVideo"
|
||||||
/>
|
/>
|
||||||
<PlayVideo
|
<MonitorLC
|
||||||
v-if="!isEdit && videoItem.videourl && !videoItem.manufacturer"
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '乐橙'"
|
||||||
|
:title="videoItem.title"
|
||||||
|
:deviceId="videoItem.videourl"
|
||||||
|
:channelId="0"
|
||||||
|
:index="videoIndex"
|
||||||
|
:width="videoWidthNoPadding"
|
||||||
|
:height="videoHeightNoPadding"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
|
:dataStyle="option.dataStyle"
|
||||||
|
@changeThisVideo="changeThisVideo"
|
||||||
|
@closeThisVideo="closeThisVideo"
|
||||||
|
/>
|
||||||
|
<MonitorTX
|
||||||
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '腾讯'"
|
||||||
|
:title="videoItem.title"
|
||||||
:videourl="videoItem.videourl"
|
:videourl="videoItem.videourl"
|
||||||
:index="videoIndex"
|
:index="videoIndex"
|
||||||
:width="videoWidthNoPadding"
|
:width="videoWidthNoPadding"
|
||||||
:height="videoHeightNoPadding"
|
:height="videoHeightNoPadding"
|
||||||
:timestamp="option.dataStyle.timestamp"
|
:timestamp="option.dataStyle.timestamp"
|
||||||
:videoLoop="option.dataStyle.videoLoop"
|
:dataStyle="option.dataStyle"
|
||||||
:videoMuted="option.dataStyle.videoMuted"
|
@changeThisVideo="changeThisVideo"
|
||||||
:videoFit="option.dataStyle.videoFit"
|
@closeThisVideo="closeThisVideo"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -146,15 +167,15 @@
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { EventBus } from '@/utils/eventBus';
|
import { EventBus } from '@/utils/eventBus';
|
||||||
import { replaceSqlParams } from '@/utils/sqlHandler';
|
import { replaceSqlParams } from '@/utils/sqlHandler';
|
||||||
|
import { Close } from '@vicons/ionicons5';
|
||||||
import {
|
import {
|
||||||
CloseButton,
|
CloseButton,
|
||||||
TypeButton,
|
TypeButton,
|
||||||
LeftTitleIcon1,
|
LeftTitleIcon1,
|
||||||
LeftTitleIcon2,
|
LeftTitleIcon2,
|
||||||
ListVideoNameIcon,
|
ListVideoNameIcon,
|
||||||
CloseVideoIcon,
|
|
||||||
} from './svg/index';
|
} from './svg/index';
|
||||||
import { MulHKmonitor, PlayVideo } from './video/index';
|
import { MonitorHK, MonitorLC, MonitorTX } from './video/index';
|
||||||
|
|
||||||
const { createMessage } = useMessage();
|
const { createMessage } = useMessage();
|
||||||
|
|
||||||
|
|
@ -639,8 +660,8 @@
|
||||||
.rightVideoItemDiv2 {
|
.rightVideoItemDiv2 {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: v-bind('`${17 / Math.sqrt(parseInt(option.dataStyle.nowType))}px`');
|
padding: v-bind('`${14 / Math.sqrt(parseInt(option.dataStyle.nowType))}px`');
|
||||||
border: v-bind('`${3 / Math.sqrt(parseInt(option.dataStyle.nowType))}px`') solid #0fab3f;
|
border: v-bind('`${6 / Math.sqrt(parseInt(option.dataStyle.nowType))}px`') solid #0fab3f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import MulHKmonitor from './mulHKmonitor.vue';
|
import MonitorHK from './monitorHK.vue';
|
||||||
import PlayVideo from './playVideo.vue';
|
import MonitorLC from './monitorLC.vue';
|
||||||
|
import MonitorTX from './monitorTX.vue';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
MulHKmonitor,
|
MonitorHK,
|
||||||
PlayVideo,
|
MonitorLC,
|
||||||
|
MonitorTX,
|
||||||
};
|
};
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
import { JSEncrypt } from 'jsencrypt';
|
import { JSEncrypt } from 'jsencrypt';
|
||||||
|
|
||||||
const props = defineProps(['serialNumberValue', 'index', 'width', 'height', 'timestamp']);
|
const props = defineProps(['serialNumberValue', 'index', 'width', 'height', 'timestamp']);
|
||||||
|
const emit = defineEmits(['changeThisVideo', 'closeThisVideo']);
|
||||||
|
|
||||||
//声明公用变量
|
//声明公用变量
|
||||||
let initCount = 0;
|
let initCount = 0;
|
||||||
|
|
@ -110,7 +111,7 @@
|
||||||
let encryptedFields = 'secret'; //加密字段,默认加密领域为secret
|
let encryptedFields = 'secret'; //加密字段,默认加密领域为secret
|
||||||
let showToolbar = 1; //是否显示工具栏,0-不显示,非0-显示
|
let showToolbar = 1; //是否显示工具栏,0-不显示,非0-显示
|
||||||
let showSmart = 1; //是否显示智能信息(如配置移动侦测后画面上的线框),0-不显示,非0-显示
|
let showSmart = 1; //是否显示智能信息(如配置移动侦测后画面上的线框),0-不显示,非0-显示
|
||||||
let buttonIDs = '0,16'; //自定义工具条按钮
|
let buttonIDs = '0'; //自定义工具条按钮
|
||||||
|
|
||||||
oWebControl
|
oWebControl
|
||||||
.JS_RequestInterface({
|
.JS_RequestInterface({
|
||||||
|
|
@ -134,6 +135,26 @@
|
||||||
.then(function (oData) {
|
.then(function (oData) {
|
||||||
// 重定大小
|
// 重定大小
|
||||||
reSizeVideo();
|
reSizeVideo();
|
||||||
|
// 单击-选择+反选择
|
||||||
|
oWebControl.JS_SetWindowControlCallback({
|
||||||
|
cbIntegrationCallBack: function (oData) {
|
||||||
|
// oData 是封装的视频 web 插件回调消息的消息体
|
||||||
|
if (oData.responseMsg.type == '1' && oData.responseMsg.msg.result == '256') {
|
||||||
|
// 选择这个视频
|
||||||
|
emit('changeThisVideo', props.index);
|
||||||
|
}
|
||||||
|
// // oData 是封装的视频 web 插件回调消息的消息体
|
||||||
|
// if (oData.responseMsg.type == '1' && oData.responseMsg.msg.result == '512') {
|
||||||
|
// // 按下关闭按钮
|
||||||
|
// emit('closeThisVideo', props.index);
|
||||||
|
// }
|
||||||
|
// oData 是封装的视频 web 插件回调消息的消息体
|
||||||
|
if (oData.responseMsg.type == '2' && oData.responseMsg.msg.result == '816') {
|
||||||
|
// 按下全部关闭按钮
|
||||||
|
emit('closeThisVideo', props.index);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 开始预览多个视频
|
// 开始预览多个视频
|
||||||
|
|
@ -227,10 +248,30 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
// 启动视频窗口
|
||||||
initPlugin();
|
initPlugin();
|
||||||
|
|
||||||
|
// 添加监听滚动事件
|
||||||
|
const elements = document.querySelectorAll('.ZhiGan_SheXiangTouModal');
|
||||||
|
if (elements.length > 0) {
|
||||||
|
// 遍历每个元素并绑定 scroll 事件
|
||||||
|
elements.forEach((element) => {
|
||||||
|
element.addEventListener('scroll', reSizeVideo);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
// 销毁视频窗口
|
||||||
closeHkVideo();
|
closeHkVideo();
|
||||||
|
|
||||||
|
// 移除监听滚动事件
|
||||||
|
const elements = document.querySelectorAll('.ZhiGan_SheXiangTouModal');
|
||||||
|
if (elements.length > 0) {
|
||||||
|
// 遍历每个元素并绑定 scroll 事件
|
||||||
|
elements.forEach((element) => {
|
||||||
|
element.removeEventListener('scroll', reSizeVideo);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|
@ -0,0 +1,284 @@
|
||||||
|
<template>
|
||||||
|
<div class="box">
|
||||||
|
<!-- 标题 -->
|
||||||
|
<div class="box-title">
|
||||||
|
<div class="left-controls">
|
||||||
|
<span
|
||||||
|
:style="{
|
||||||
|
fontSize: props.dataStyle.videoTitleFontSize + 'px',
|
||||||
|
color: props.dataStyle.videoTitleFontColor,
|
||||||
|
marginLeft: '10px',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ props.title }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="right-controls">
|
||||||
|
<n-button quaternary @click="closeVideo">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<Close
|
||||||
|
:style="{
|
||||||
|
width: props.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
height: props.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
fontSize: props.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
color: props.dataStyle.closeVideoIconColor,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 视频 -->
|
||||||
|
<div class="box-container">
|
||||||
|
<div :id="'root' + props.index + props.timestamp" @click="clickThisVideo" />
|
||||||
|
</div>
|
||||||
|
<!-- 控制栏 -->
|
||||||
|
<div class="box-controls">
|
||||||
|
<div class="left-controls">
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="playOrPauseClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<Pause
|
||||||
|
v-if="control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<CaretForward
|
||||||
|
v-if="!control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="volumeClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<VolumeHigh
|
||||||
|
v-if="control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<VolumeMute
|
||||||
|
v-if="!control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="right-controls">
|
||||||
|
<n-button quaternary @click="fullScreenClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<ExpandOutlined
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, onUnmounted, watch, ref } from 'vue';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { ExpandOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { Close, Pause, CaretForward, VolumeHigh, VolumeMute } from '@vicons/ionicons5';
|
||||||
|
|
||||||
|
let BASE_URL = 'http://111.17.207.220:9001/api';
|
||||||
|
|
||||||
|
const props = defineProps([
|
||||||
|
'title',
|
||||||
|
'deviceId',
|
||||||
|
'channelId',
|
||||||
|
'index',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'timestamp',
|
||||||
|
'dataStyle',
|
||||||
|
]);
|
||||||
|
const emit = defineEmits(['changeThisVideo', 'closeThisVideo']);
|
||||||
|
|
||||||
|
let clPlayer: any = null;
|
||||||
|
|
||||||
|
// 点击视频内容
|
||||||
|
function clickThisVideo() {
|
||||||
|
emit('changeThisVideo', props.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭此视频;
|
||||||
|
function closeVideo() {
|
||||||
|
closeMonitorVideo();
|
||||||
|
emit('closeThisVideo', props.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始播放/暂停播放
|
||||||
|
const control_playOrPause = ref(true);
|
||||||
|
// 音量:true为静音
|
||||||
|
const control_volume = ref(true);
|
||||||
|
|
||||||
|
// 开始播放/暂停播放方法
|
||||||
|
function playOrPauseClick() {
|
||||||
|
control_playOrPause.value = !control_playOrPause.value;
|
||||||
|
if (control_playOrPause.value) {
|
||||||
|
clPlayer.play();
|
||||||
|
} else {
|
||||||
|
clPlayer.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 音量
|
||||||
|
function volumeClick() {
|
||||||
|
control_volume.value = !control_volume.value;
|
||||||
|
if (control_volume.value) {
|
||||||
|
clPlayer.volume(0);
|
||||||
|
} else {
|
||||||
|
clPlayer.volume(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全屏
|
||||||
|
function fullScreenClick() {
|
||||||
|
clPlayer.fullScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取kitToken
|
||||||
|
let kitToken = null;
|
||||||
|
function getKitToken(deviceId, channelId) {
|
||||||
|
axios({
|
||||||
|
method: 'post',
|
||||||
|
url: BASE_URL + '/Camera/getKitToken?deviceId=' + deviceId + '&channelId=0' + '&type=0',
|
||||||
|
}).then((res) => {
|
||||||
|
kitToken = res.data.result.data.kitToken;
|
||||||
|
loadMonitorVideo(deviceId, kitToken, channelId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始
|
||||||
|
function loadMonitorVideo(deviceId, kitToken, channelId) {
|
||||||
|
// 结束上一个
|
||||||
|
closeMonitorVideo();
|
||||||
|
|
||||||
|
clPlayer = new imouPlayer({
|
||||||
|
id: 'root' + props.index + props.timestamp,
|
||||||
|
width: props.width,
|
||||||
|
height: props.height - 70,
|
||||||
|
deviceId: deviceId,
|
||||||
|
token: kitToken,
|
||||||
|
channelId: channelId,
|
||||||
|
type: 1,
|
||||||
|
streamId: 0,
|
||||||
|
recordType: 'cloud',
|
||||||
|
code: '',
|
||||||
|
controls: true,
|
||||||
|
});
|
||||||
|
clPlayer.volume(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 结束
|
||||||
|
function closeMonitorVideo() {
|
||||||
|
if (clPlayer != null) {
|
||||||
|
clPlayer.destroy();
|
||||||
|
clPlayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测视频id
|
||||||
|
watch(
|
||||||
|
() => props.deviceId,
|
||||||
|
() => {
|
||||||
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
// 检测宽度
|
||||||
|
watch(
|
||||||
|
() => props.width,
|
||||||
|
() => {
|
||||||
|
clPlayer = new imouPlayer({
|
||||||
|
id: 'root' + props.index + props.timestamp,
|
||||||
|
width: props.width,
|
||||||
|
height: props.height - 70,
|
||||||
|
deviceId: props.deviceId,
|
||||||
|
token: kitToken,
|
||||||
|
channelId: props.channelId,
|
||||||
|
type: 1,
|
||||||
|
streamId: 0,
|
||||||
|
recordType: 'cloud',
|
||||||
|
code: '',
|
||||||
|
controls: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
control_volume.value = props.dataStyle.videoMuted;
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
closeMonitorVideo();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.box {
|
||||||
|
width: v-bind('`${props.width}px`');
|
||||||
|
height: v-bind('`${props.height}px`');
|
||||||
|
z-index: 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-title {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
align-items: center;
|
||||||
|
background: #000000;
|
||||||
|
height: 35px;
|
||||||
|
width: 100%;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-container {
|
||||||
|
width: v-bind('`${props.width}px`');
|
||||||
|
height: v-bind('`${props.height-70}px`');
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-controls {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
align-items: center;
|
||||||
|
background: #000000;
|
||||||
|
height: 35px;
|
||||||
|
width: 100%;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-controls {
|
||||||
|
display: flex;
|
||||||
|
justify-self: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-controls {
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,277 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- 标题 -->
|
||||||
|
<div class="box-title">
|
||||||
|
<div class="left-title">
|
||||||
|
<span
|
||||||
|
:style="{
|
||||||
|
fontSize: props.dataStyle.videoTitleFontSize + 'px',
|
||||||
|
color: props.dataStyle.videoTitleFontColor,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ props.title }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="right-title">
|
||||||
|
<n-button quaternary @click="closeVideo">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<Close
|
||||||
|
:style="{
|
||||||
|
width: props.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
height: props.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
fontSize: props.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
color: props.dataStyle.closeVideoIconColor,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 视频 -->
|
||||||
|
<video
|
||||||
|
:id="'ZhiGan_SheXiangTouModal' + props.index + props.timestamp"
|
||||||
|
class="TCPlayer-video-contaiiner"
|
||||||
|
preload="auto"
|
||||||
|
crossOrigin="anonymous"
|
||||||
|
playsinline
|
||||||
|
autoplay
|
||||||
|
:loop="props.dataStyle.videoLoop"
|
||||||
|
:muted="props.dataStyle.videoMuted"
|
||||||
|
@click="clickThisVideo"
|
||||||
|
/>
|
||||||
|
<!-- 控制栏 -->
|
||||||
|
<div class="box-controls">
|
||||||
|
<div class="left-controls">
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="playOrPauseClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<Pause
|
||||||
|
v-if="control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<CaretForward
|
||||||
|
v-if="!control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="volumeClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<VolumeHigh
|
||||||
|
v-if="control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<VolumeMute
|
||||||
|
v-if="!control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="right-controls">
|
||||||
|
<n-button quaternary @click="fullScreenClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<ExpandOutlined
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { nextTick, onMounted, onUnmounted, watch, ref } from 'vue';
|
||||||
|
import { ExpandOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { Close, Pause, CaretForward, VolumeHigh, VolumeMute } from '@vicons/ionicons5';
|
||||||
|
|
||||||
|
const props = defineProps([
|
||||||
|
'title',
|
||||||
|
'videourl',
|
||||||
|
'index',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'timestamp',
|
||||||
|
'dataStyle',
|
||||||
|
]);
|
||||||
|
const emit = defineEmits(['changeThisVideo', 'closeThisVideo']);
|
||||||
|
|
||||||
|
// 关闭此视频;
|
||||||
|
function closeVideo() {
|
||||||
|
closePlayerVideo();
|
||||||
|
emit('closeThisVideo', props.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始播放/暂停播放
|
||||||
|
const control_playOrPause = ref(true);
|
||||||
|
// 音量:true为静音
|
||||||
|
const control_volume = ref(true);
|
||||||
|
|
||||||
|
// 开始播放/暂停播放方法
|
||||||
|
function playOrPauseClick() {
|
||||||
|
control_playOrPause.value = !control_playOrPause.value;
|
||||||
|
if (control_playOrPause.value) {
|
||||||
|
txPlayer.play();
|
||||||
|
} else {
|
||||||
|
txPlayer.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 音量
|
||||||
|
function volumeClick() {
|
||||||
|
control_volume.value = !control_volume.value;
|
||||||
|
if (control_volume.value) {
|
||||||
|
txPlayer.volume(0);
|
||||||
|
} else {
|
||||||
|
txPlayer.volume(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全屏
|
||||||
|
function fullScreenClick() {
|
||||||
|
txPlayer.requestFullscreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.videourl,
|
||||||
|
() => {
|
||||||
|
handlerPlayVideo();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
watch(
|
||||||
|
() => props.width,
|
||||||
|
() => {
|
||||||
|
handlerPlayVideo();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// 视频控件初始化
|
||||||
|
let txPlayer: any = null;
|
||||||
|
function handlerPlayVideo() {
|
||||||
|
nextTick(function () {
|
||||||
|
if (txPlayer) {
|
||||||
|
txPlayer.src(props.videourl);
|
||||||
|
txPlayer.width(props.width);
|
||||||
|
txPlayer.height(props.height - 70);
|
||||||
|
} else {
|
||||||
|
txPlayer = TCPlayer('ZhiGan_SheXiangTouModal' + props.index + props.timestamp, {
|
||||||
|
width: props.width,
|
||||||
|
height: props.height - 70,
|
||||||
|
controls: false,
|
||||||
|
});
|
||||||
|
txPlayer.src(props.videourl);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭此视频
|
||||||
|
function closePlayerVideo() {
|
||||||
|
if (txPlayer) {
|
||||||
|
txPlayer.dispose();
|
||||||
|
txPlayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击视频内容
|
||||||
|
function clickThisVideo() {
|
||||||
|
emit('changeThisVideo', props.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
handlerPlayVideo();
|
||||||
|
control_volume.value = props.videoMuted;
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
closePlayerVideo();
|
||||||
|
});
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
handlerPlayVideo,
|
||||||
|
closePlayerVideo,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.box-title {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
align-items: center;
|
||||||
|
background: #000000;
|
||||||
|
height: 35px;
|
||||||
|
width: 100%;
|
||||||
|
gap: 10px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-title {
|
||||||
|
position: absolute;
|
||||||
|
top: 0%;
|
||||||
|
left: 0%;
|
||||||
|
z-index: 100;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
.right-title {
|
||||||
|
position: absolute;
|
||||||
|
top: -10%;
|
||||||
|
right: 0%;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
video {
|
||||||
|
display: block;
|
||||||
|
object-fit: v-bind('props.dataStyle.videoFit');
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .vjs-live-display {
|
||||||
|
width: 40px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .vjs-button {
|
||||||
|
width: 20px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-controls {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
align-items: center;
|
||||||
|
background: #000000;
|
||||||
|
height: 35px;
|
||||||
|
width: 100%;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-controls {
|
||||||
|
display: flex;
|
||||||
|
justify-self: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-controls {
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<video
|
|
||||||
:id="'ZhiGan_SheXiangTouModal' + props.index + props.timestamp"
|
|
||||||
class="TCPlayer-video-contaiiner"
|
|
||||||
preload="auto"
|
|
||||||
crossOrigin="anonymous"
|
|
||||||
playsinline
|
|
||||||
autoplay
|
|
||||||
:loop="props.videoLoop"
|
|
||||||
:muted="props.videoMuted"
|
|
||||||
:style="{
|
|
||||||
width: props.width + 'px',
|
|
||||||
height: props.height + 'px',
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { nextTick, onMounted, onUnmounted, watch } from 'vue';
|
|
||||||
|
|
||||||
const props = defineProps([
|
|
||||||
'videourl',
|
|
||||||
'index',
|
|
||||||
'width',
|
|
||||||
'height',
|
|
||||||
'timestamp',
|
|
||||||
'videoLoop',
|
|
||||||
'videoMuted',
|
|
||||||
'videoFit',
|
|
||||||
]);
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.videourl,
|
|
||||||
() => {
|
|
||||||
handlerPlayVideo();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
watch(
|
|
||||||
() => props.width,
|
|
||||||
() => {
|
|
||||||
handlerPlayVideo();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// 视频控件初始化
|
|
||||||
let player: any = null;
|
|
||||||
|
|
||||||
function handlerPlayVideo() {
|
|
||||||
nextTick(function () {
|
|
||||||
if (player) {
|
|
||||||
player.src(props.videourl);
|
|
||||||
} else {
|
|
||||||
player = TCPlayer('ZhiGan_SheXiangTouModal' + props.index + props.timestamp, {});
|
|
||||||
player.src(props.videourl);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function closePlayerVideo() {
|
|
||||||
if (player) {
|
|
||||||
player.dispose();
|
|
||||||
player = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
handlerPlayVideo();
|
|
||||||
});
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
closePlayerVideo();
|
|
||||||
});
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
handlerPlayVideo,
|
|
||||||
closePlayerVideo,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
video {
|
|
||||||
display: block;
|
|
||||||
object-fit: v-bind('props.videoFit');
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .vjs-live-display {
|
|
||||||
width: 40px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .vjs-button {
|
|
||||||
width: 20px !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -23,32 +23,47 @@
|
||||||
{
|
{
|
||||||
"title":"DJA-72无人机监控画面",
|
"title":"DJA-72无人机监控画面",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"DJ-057无人机监控画面",
|
"title":"DJ-057无人机监控画面",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"DJA-20无人机监控画面",
|
"title":"DJA-20无人机监控画面",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"DJA-035无人机监控画面",
|
"title":"DJA-035无人机监控画面",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"DJA-11无人机监控画面",
|
"title":"DJA-11无人机监控画面",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"DJ-021无人机监控画面",
|
"title":"DJ-021无人机监控画面",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "白马关通天沟",
|
||||||
|
"videourl": "8H03AA1PAG97234",
|
||||||
|
"manufacturer": "乐橙"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "可落",
|
||||||
|
"videourl": "8H03AA1PAG8D9BF",
|
||||||
|
"manufacturer": "乐橙"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "天宝山林场",
|
||||||
|
"videourl": "8L0995DPAG11E58",
|
||||||
|
"manufacturer": "乐橙"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@
|
||||||
:height="`${option.dataStyle.videoheight - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
|
:height="`${option.dataStyle.videoheight - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
|
||||||
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
||||||
/>
|
/>
|
||||||
<MulHKmonitor
|
<MonitorHK
|
||||||
v-if="!isEdit && item.manufacturer == '海康'"
|
v-if="!isEdit && item.manufacturer == '海康'"
|
||||||
:index="index"
|
:index="index"
|
||||||
:serialNumberValue="item.videourl"
|
:serialNumberValue="item.videourl"
|
||||||
|
|
@ -65,8 +65,18 @@
|
||||||
:height="`${option.dataStyle.videoheight - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
|
:height="`${option.dataStyle.videoheight - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
|
||||||
:timestamp="option.dataStyle.timestamp"
|
:timestamp="option.dataStyle.timestamp"
|
||||||
/>
|
/>
|
||||||
<PlayVideo
|
<MonitorLC
|
||||||
v-if="!isEdit && !item.manufacturer"
|
v-if="!isEdit && item.manufacturer == '乐橙'"
|
||||||
|
:deviceId="item.videourl"
|
||||||
|
:channelId="0"
|
||||||
|
:index="index"
|
||||||
|
:width="`${option.dataStyle.videowidth - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
|
||||||
|
:height="`${option.dataStyle.videoheight - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
|
/>
|
||||||
|
<MonitorTX
|
||||||
|
v-if="!isEdit && item.manufacturer == '腾讯'"
|
||||||
:videourl="item.videourl"
|
:videourl="item.videourl"
|
||||||
:index="index"
|
:index="index"
|
||||||
:width="`${option.dataStyle.videowidth - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
|
:width="`${option.dataStyle.videowidth - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
|
||||||
|
|
@ -109,7 +119,7 @@
|
||||||
import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
|
import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import Title from './svg/title.vue';
|
import Title from './svg/title.vue';
|
||||||
import { MulHKmonitor, PlayVideo } from './video/index';
|
import { MonitorHK, MonitorLC, MonitorTX } from './video/index';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
chartConfig: {
|
chartConfig: {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import MulHKmonitor from './mulHKmonitor.vue';
|
import MonitorHK from './monitorHK.vue';
|
||||||
import PlayVideo from './playVideo.vue';
|
import MonitorLC from './monitorLC.vue';
|
||||||
|
import MonitorTX from './monitorTX.vue';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
MulHKmonitor,
|
MonitorHK,
|
||||||
PlayVideo,
|
MonitorLC,
|
||||||
|
MonitorTX,
|
||||||
};
|
};
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, onUnmounted, watch, defineProps, defineExpose, ref, computed } from 'vue';
|
import { onMounted, onUnmounted, watch, nextTick, ref, computed } from 'vue';
|
||||||
import { JSEncrypt } from 'jsencrypt';
|
import { JSEncrypt } from 'jsencrypt';
|
||||||
|
|
||||||
const props = defineProps(['serialNumberValue', 'index', 'width', 'height', 'timestamp']);
|
const props = defineProps(['serialNumberValue', 'index', 'width', 'height', 'timestamp']);
|
||||||
|
|
@ -132,27 +132,12 @@
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
.then(function (oData) {
|
.then(function (oData) {
|
||||||
// 实际宽高
|
// 重定大小
|
||||||
let width = props.width;
|
reSizeVideo();
|
||||||
let height = props.height;
|
// 双击-全屏
|
||||||
const divElement = document.getElementById('camera-box-' + props.index);
|
|
||||||
if (divElement) {
|
|
||||||
const rect = divElement.getBoundingClientRect();
|
|
||||||
const rectWidth = rect.width;
|
|
||||||
const rectHeight = rect.height;
|
|
||||||
if (rectWidth < width) {
|
|
||||||
width = rectWidth;
|
|
||||||
}
|
|
||||||
if (rectHeight < height) {
|
|
||||||
height = rectHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
oWebControl.JS_Resize(width, height); // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
|
|
||||||
|
|
||||||
oWebControl.JS_SetWindowControlCallback({
|
oWebControl.JS_SetWindowControlCallback({
|
||||||
cbIntegrationCallBack: function (oData) {
|
cbIntegrationCallBack: function (oData) {
|
||||||
// oData 是封装的视频 web 插件回调消息的消息体
|
// oData 是封装的视频 web 插件回调消息的消息体
|
||||||
// 双击-全屏
|
|
||||||
if (oData.responseMsg.type == '7') {
|
if (oData.responseMsg.type == '7') {
|
||||||
setFullScreen();
|
setFullScreen();
|
||||||
}
|
}
|
||||||
|
|
@ -210,6 +195,27 @@
|
||||||
return encrypt.encrypt(value);
|
return encrypt.encrypt(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 重定大小
|
||||||
|
function reSizeVideo() {
|
||||||
|
if (oWebControl != null) {
|
||||||
|
// 实际宽高
|
||||||
|
let width = props.width;
|
||||||
|
let height = props.height;
|
||||||
|
const divElement = document.getElementById('camera-box-' + props.index);
|
||||||
|
if (divElement) {
|
||||||
|
const rect = divElement.getBoundingClientRect();
|
||||||
|
const rectWidth = rect.width;
|
||||||
|
const rectHeight = rect.height;
|
||||||
|
if (rectWidth < width) {
|
||||||
|
width = rectWidth;
|
||||||
|
}
|
||||||
|
if (rectHeight < height) {
|
||||||
|
height = rectHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oWebControl.JS_Resize(width, height); // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
|
||||||
|
}
|
||||||
|
}
|
||||||
// 全屏
|
// 全屏
|
||||||
function setFullScreen() {
|
function setFullScreen() {
|
||||||
oWebControl.JS_RequestInterface({
|
oWebControl.JS_RequestInterface({
|
||||||
|
|
@ -217,16 +223,42 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.serialNumberValue,
|
||||||
|
() => {
|
||||||
|
// 初始化播放内容
|
||||||
|
init();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// 推送消息
|
// 推送消息
|
||||||
function cbIntegrationCallBack(oData) {
|
function cbIntegrationCallBack(oData) {
|
||||||
// showCBInfo(JSON.stringify(oData.responseMsg));
|
// showCBInfo(JSON.stringify(oData.responseMsg));
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
// 启动视频窗口
|
||||||
initPlugin();
|
initPlugin();
|
||||||
|
// 添加监听滚动事件
|
||||||
|
const elements = document.querySelectorAll('.ZhiGan_WuRenJiShiShiHuaMian');
|
||||||
|
if (elements.length > 0) {
|
||||||
|
// 遍历每个元素并绑定 scroll 事件
|
||||||
|
elements.forEach((element) => {
|
||||||
|
element.addEventListener('scroll', reSizeVideo);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
// 销毁视频窗口
|
||||||
closeHkVideo();
|
closeHkVideo();
|
||||||
|
// 移除监听滚动事件
|
||||||
|
const elements = document.querySelectorAll('.ZhiGan_WuRenJiShiShiHuaMian');
|
||||||
|
if (elements.length > 0) {
|
||||||
|
// 遍历每个元素并绑定 scroll 事件
|
||||||
|
elements.forEach((element) => {
|
||||||
|
element.removeEventListener('scroll', reSizeVideo);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|
@ -0,0 +1,208 @@
|
||||||
|
<template>
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-container">
|
||||||
|
<div :id="'root' + props.index + props.timestamp"></div>
|
||||||
|
</div>
|
||||||
|
<div class="box-controls">
|
||||||
|
<div class="left-controls">
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="playOrPauseClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<Pause
|
||||||
|
v-if="control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<CaretForward
|
||||||
|
v-if="!control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="volumeClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<VolumeHigh
|
||||||
|
v-if="!control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<VolumeMute
|
||||||
|
v-if="control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="right-controls">
|
||||||
|
<n-button quaternary @click="fullScreenClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<ExpandOutlined
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, onUnmounted, watch, ref } from 'vue';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { ExpandOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { Pause, CaretForward, VolumeHigh, VolumeMute } from '@vicons/ionicons5';
|
||||||
|
|
||||||
|
let BASE_URL = 'http://111.17.207.220:9001/api';
|
||||||
|
|
||||||
|
const props = defineProps([
|
||||||
|
'deviceId',
|
||||||
|
'channelId',
|
||||||
|
'index',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'timestamp',
|
||||||
|
'videoMuted',
|
||||||
|
]);
|
||||||
|
let clPlayer: any = null;
|
||||||
|
|
||||||
|
// 开始播放/暂停播放
|
||||||
|
const control_playOrPause = ref(true);
|
||||||
|
// 音量:true为静音
|
||||||
|
const control_volume = ref(true);
|
||||||
|
// 全屏
|
||||||
|
const control_fullScreen = ref(false);
|
||||||
|
|
||||||
|
// 开始播放/暂停播放方法
|
||||||
|
function playOrPauseClick() {
|
||||||
|
control_playOrPause.value = !control_playOrPause.value;
|
||||||
|
if (control_playOrPause.value) {
|
||||||
|
clPlayer.play();
|
||||||
|
} else {
|
||||||
|
clPlayer.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 音量
|
||||||
|
function volumeClick() {
|
||||||
|
control_volume.value = !control_volume.value;
|
||||||
|
if (control_volume.value) {
|
||||||
|
clPlayer.volume(0);
|
||||||
|
} else {
|
||||||
|
clPlayer.volume(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全屏
|
||||||
|
function fullScreenClick() {
|
||||||
|
clPlayer.fullScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取kitToken
|
||||||
|
function getKitToken(deviceId, channelId) {
|
||||||
|
axios({
|
||||||
|
method: 'post',
|
||||||
|
url: BASE_URL + '/Camera/getKitToken?deviceId=' + deviceId + '&channelId=0' + '&type=0',
|
||||||
|
}).then((res) => {
|
||||||
|
let kitToken = res.data.result.data.kitToken;
|
||||||
|
loadMonitorVideo(deviceId, kitToken, channelId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始
|
||||||
|
function loadMonitorVideo(deviceId, kitToken, channelId) {
|
||||||
|
// 结束上一个
|
||||||
|
closeMonitorVideo();
|
||||||
|
|
||||||
|
clPlayer = new imouPlayer({
|
||||||
|
id: 'root' + props.index + props.timestamp,
|
||||||
|
width: props.width,
|
||||||
|
height: props.height - 35,
|
||||||
|
deviceId: deviceId,
|
||||||
|
token: kitToken,
|
||||||
|
channelId: channelId,
|
||||||
|
type: 1,
|
||||||
|
streamId: 0,
|
||||||
|
recordType: 'cloud',
|
||||||
|
code: '',
|
||||||
|
controls: true,
|
||||||
|
});
|
||||||
|
clPlayer.volume(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 结束
|
||||||
|
function closeMonitorVideo() {
|
||||||
|
if (clPlayer != null) {
|
||||||
|
clPlayer.destroy();
|
||||||
|
clPlayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.deviceId,
|
||||||
|
() => {
|
||||||
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
control_volume.value = props.videoMuted;
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
closeMonitorVideo();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.box {
|
||||||
|
width: v-bind('`${props.width}px`');
|
||||||
|
height: v-bind('`${props.height}px`');
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
.box-container {
|
||||||
|
width: v-bind('`${props.width}px`');
|
||||||
|
height: v-bind('`${props.height-35}px`');
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-controls {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
align-items: center;
|
||||||
|
background: #000000;
|
||||||
|
height: 35px;
|
||||||
|
width: 100%;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-controls {
|
||||||
|
display: flex;
|
||||||
|
justify-self: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-controls {
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -15,7 +15,12 @@
|
||||||
{
|
{
|
||||||
"title":"费县马庄镇陈家鱼后村南斜坡后村",
|
"title":"费县马庄镇陈家鱼后村南斜坡后村",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title":"可落",
|
||||||
|
"videourl": "8H03AA1PAG8D9BF",
|
||||||
|
"manufacturer": "乐橙"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -126,10 +126,27 @@
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
||||||
preview-disabled
|
|
||||||
/>
|
/>
|
||||||
<PlayVideo
|
<MonitorHK
|
||||||
v-if="!isEdit && videoItem.videourl && !videoItem.manufacturer"
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '海康'"
|
||||||
|
:index="index + '-' + videoIndex"
|
||||||
|
:serialNumberValue="videoItem.videourl"
|
||||||
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
/>
|
||||||
|
<MonitorLC
|
||||||
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '乐橙'"
|
||||||
|
:deviceId="videoItem.videourl"
|
||||||
|
:channelId="0"
|
||||||
|
:index="index + '-' + videoIndex"
|
||||||
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
|
/>
|
||||||
|
<MonitorTX
|
||||||
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '腾讯'"
|
||||||
:videourl="videoItem.videourl"
|
:videourl="videoItem.videourl"
|
||||||
:index="index + '-' + videoIndex"
|
:index="index + '-' + videoIndex"
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
|
@ -139,14 +156,6 @@
|
||||||
:videoMuted="option.dataStyle.videoMuted"
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
:videoFit="option.dataStyle.videoFit"
|
:videoFit="option.dataStyle.videoFit"
|
||||||
/>
|
/>
|
||||||
<MulHKmonitor
|
|
||||||
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '海康'"
|
|
||||||
:index="index + '-' + videoIndex"
|
|
||||||
:serialNumberValue="videoItem.videourl"
|
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
|
||||||
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
|
||||||
:timestamp="option.dataStyle.timestamp"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 单个 -->
|
<!-- 单个 -->
|
||||||
|
|
@ -161,10 +170,27 @@
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
||||||
preview-disabled
|
|
||||||
/>
|
/>
|
||||||
<PlayVideo
|
<MonitorHK
|
||||||
v-if="!isEdit && item.videos.videourl && !item.videos.manufacturer"
|
v-if="!isEdit && item.videos.videourl && item.videos.manufacturer == '海康'"
|
||||||
|
:index="index + '-' + videoIndex"
|
||||||
|
:serialNumberValue="item.videos.videourl"
|
||||||
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
/>
|
||||||
|
<MonitorLC
|
||||||
|
v-if="!isEdit && item.videos.videourl && item.videos.manufacturer == '乐橙'"
|
||||||
|
:deviceId="item.videos.videourl"
|
||||||
|
:channelId="0"
|
||||||
|
:index="index"
|
||||||
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
|
/>
|
||||||
|
<MonitorTX
|
||||||
|
v-if="!isEdit && item.videos.videourl && item.videos.manufacturer == '腾讯'"
|
||||||
:videourl="item.videos.videourl"
|
:videourl="item.videos.videourl"
|
||||||
:index="index + '-0'"
|
:index="index + '-0'"
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
|
@ -174,14 +200,6 @@
|
||||||
:videoMuted="option.dataStyle.videoMuted"
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
:videoFit="option.dataStyle.videoFit"
|
:videoFit="option.dataStyle.videoFit"
|
||||||
/>
|
/>
|
||||||
<MulHKmonitor
|
|
||||||
v-if="!isEdit && item.videos.videourl && item.videos.manufacturer == '海康'"
|
|
||||||
:index="index + '-' + videoIndex"
|
|
||||||
:serialNumberValue="item.videos.videourl"
|
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
|
||||||
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
|
||||||
:timestamp="option.dataStyle.timestamp"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -200,7 +218,7 @@
|
||||||
import { replaceSqlParams } from '@/utils/sqlHandler';
|
import { replaceSqlParams } from '@/utils/sqlHandler';
|
||||||
import Title from './svg/title.vue';
|
import Title from './svg/title.vue';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { MulHKmonitor, PlayVideo } from './video/index';
|
import { MonitorHK, MonitorLC, MonitorTX } from './video/index';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
chartConfig: {
|
chartConfig: {
|
||||||
|
|
@ -313,7 +331,7 @@
|
||||||
|
|
||||||
.timeLineVideoDivTitle {
|
.timeLineVideoDivTitle {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 10;
|
z-index: 100;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
left: 5px;
|
left: 5px;
|
||||||
font-size: v-bind('`${option.dataStyle.videoTitleFontSize}px`');
|
font-size: v-bind('`${option.dataStyle.videoTitleFontSize}px`');
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import MulHKmonitor from './mulHKmonitor.vue';
|
import MonitorHK from './monitorHK.vue';
|
||||||
import PlayVideo from './playVideo.vue';
|
import MonitorLC from './monitorLC.vue';
|
||||||
|
import MonitorTX from './monitorTX.vue';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
MulHKmonitor,
|
MonitorHK,
|
||||||
PlayVideo,
|
MonitorLC,
|
||||||
|
MonitorTX,
|
||||||
};
|
};
|
||||||
|
|
@ -0,0 +1,208 @@
|
||||||
|
<template>
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-container">
|
||||||
|
<div :id="'root' + props.index + props.timestamp"></div>
|
||||||
|
</div>
|
||||||
|
<div class="box-controls">
|
||||||
|
<div class="left-controls">
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="playOrPauseClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<Pause
|
||||||
|
v-if="control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<CaretForward
|
||||||
|
v-if="!control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="volumeClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<VolumeHigh
|
||||||
|
v-if="!control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<VolumeMute
|
||||||
|
v-if="control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="right-controls">
|
||||||
|
<n-button quaternary @click="fullScreenClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<ExpandOutlined
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, onUnmounted, watch, ref } from 'vue';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { ExpandOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { Pause, CaretForward, VolumeHigh, VolumeMute } from '@vicons/ionicons5';
|
||||||
|
|
||||||
|
let BASE_URL = 'http://111.17.207.220:9001/api';
|
||||||
|
|
||||||
|
const props = defineProps([
|
||||||
|
'deviceId',
|
||||||
|
'channelId',
|
||||||
|
'index',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'timestamp',
|
||||||
|
'videoMuted',
|
||||||
|
]);
|
||||||
|
let clPlayer: any = null;
|
||||||
|
|
||||||
|
// 开始播放/暂停播放
|
||||||
|
const control_playOrPause = ref(true);
|
||||||
|
// 音量:true为静音
|
||||||
|
const control_volume = ref(true);
|
||||||
|
// 全屏
|
||||||
|
const control_fullScreen = ref(false);
|
||||||
|
|
||||||
|
// 开始播放/暂停播放方法
|
||||||
|
function playOrPauseClick() {
|
||||||
|
control_playOrPause.value = !control_playOrPause.value;
|
||||||
|
if (control_playOrPause.value) {
|
||||||
|
clPlayer.play();
|
||||||
|
} else {
|
||||||
|
clPlayer.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 音量
|
||||||
|
function volumeClick() {
|
||||||
|
control_volume.value = !control_volume.value;
|
||||||
|
if (control_volume.value) {
|
||||||
|
clPlayer.volume(0);
|
||||||
|
} else {
|
||||||
|
clPlayer.volume(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全屏
|
||||||
|
function fullScreenClick() {
|
||||||
|
clPlayer.fullScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取kitToken
|
||||||
|
function getKitToken(deviceId, channelId) {
|
||||||
|
axios({
|
||||||
|
method: 'post',
|
||||||
|
url: BASE_URL + '/Camera/getKitToken?deviceId=' + deviceId + '&channelId=0' + '&type=0',
|
||||||
|
}).then((res) => {
|
||||||
|
let kitToken = res.data.result.data.kitToken;
|
||||||
|
loadMonitorVideo(deviceId, kitToken, channelId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始
|
||||||
|
function loadMonitorVideo(deviceId, kitToken, channelId) {
|
||||||
|
// 结束上一个
|
||||||
|
closeMonitorVideo();
|
||||||
|
|
||||||
|
clPlayer = new imouPlayer({
|
||||||
|
id: 'root' + props.index + props.timestamp,
|
||||||
|
width: props.width,
|
||||||
|
height: props.height - 25,
|
||||||
|
deviceId: deviceId,
|
||||||
|
token: kitToken,
|
||||||
|
channelId: channelId,
|
||||||
|
type: 1,
|
||||||
|
streamId: 0,
|
||||||
|
recordType: 'cloud',
|
||||||
|
code: '',
|
||||||
|
controls: true,
|
||||||
|
});
|
||||||
|
clPlayer.volume(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 结束
|
||||||
|
function closeMonitorVideo() {
|
||||||
|
if (clPlayer != null) {
|
||||||
|
clPlayer.destroy();
|
||||||
|
clPlayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.deviceId,
|
||||||
|
() => {
|
||||||
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
control_volume.value = props.videoMuted;
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
closeMonitorVideo();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.box {
|
||||||
|
width: v-bind('`${props.width}px`');
|
||||||
|
height: v-bind('`${props.height}px`');
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
.box-container {
|
||||||
|
width: v-bind('`${props.width}px`');
|
||||||
|
height: v-bind('`${props.height-25}px`');
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-controls {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
align-items: center;
|
||||||
|
background: #000000;
|
||||||
|
height: 25px;
|
||||||
|
width: 100%;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-controls {
|
||||||
|
display: flex;
|
||||||
|
justify-self: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-controls {
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<video
|
<video
|
||||||
:id="'ZhiGan_ModalTimeLine' + props.index + props.timestamp"
|
:id="'HuoQingDetailTimeLine' + props.index + props.timestamp"
|
||||||
class="TCPlayer-video-contaiiner"
|
class="TCPlayer-video-contaiiner"
|
||||||
preload="auto"
|
preload="auto"
|
||||||
crossOrigin="anonymous"
|
crossOrigin="anonymous"
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
if (player) {
|
if (player) {
|
||||||
player.src(props.videourl);
|
player.src(props.videourl);
|
||||||
} else {
|
} else {
|
||||||
player = TCPlayer('ZhiGan_ModalTimeLine' + props.index + props.timestamp, {});
|
player = TCPlayer('HuoQingDetailTimeLine' + props.index + props.timestamp, {});
|
||||||
player.src(props.videourl);
|
player.src(props.videourl);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -10,7 +10,13 @@
|
||||||
<div class="filter-title">
|
<div class="filter-title">
|
||||||
<div class="filter-item-title" style="position: relative;">
|
<div class="filter-item-title" style="position: relative;">
|
||||||
字段
|
字段
|
||||||
<div class="mark">{{ `条件${index+1}` }}</div>
|
<div class="mark"
|
||||||
|
@mouseenter="showCancel = index"
|
||||||
|
@mouseleave="showCancel = null"
|
||||||
|
@click="cancelFilterItem(index)"
|
||||||
|
>
|
||||||
|
{{ showCancel == index? `取消`: `条件${index+1}` }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-item-title">类型</div>
|
<div class="filter-item-title">类型</div>
|
||||||
<div class="filter-item-title">条件</div>
|
<div class="filter-item-title">条件</div>
|
||||||
|
|
@ -24,6 +30,7 @@
|
||||||
:options="props.tableColumn"
|
:options="props.tableColumn"
|
||||||
style="width: 190px;height: 43px;"
|
style="width: 190px;height: 43px;"
|
||||||
placeholder="请选择相关字段"
|
placeholder="请选择相关字段"
|
||||||
|
@change="getFilterNumber"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-item-value">{{ getTableColumnType(item.field,item) }}</div>
|
<div class="filter-item-value">{{ getTableColumnType(item.field,item) }}</div>
|
||||||
|
|
@ -34,10 +41,11 @@
|
||||||
:options="item.type == 'numeric'? numberOptions: stringOptions"
|
:options="item.type == 'numeric'? numberOptions: stringOptions"
|
||||||
style="width: 190px;height: 43px;"
|
style="width: 190px;height: 43px;"
|
||||||
placeholder="请选择相关条件"
|
placeholder="请选择相关条件"
|
||||||
|
@change="getFilterNumber"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-item-value">
|
<div class="filter-item-value">
|
||||||
<a-input v-model:value="item.value" placeholder="请输入相关内容" style="width: 300px;height: 43px;" />
|
<a-input v-model:value="item.value" placeholder="请输入相关内容" style="width: 300px;height: 43px;" @change="getFilterNumber"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -54,10 +62,14 @@
|
||||||
</BasicTable>
|
</BasicTable>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
|
<div class="filter-number" v-if="total">{{`共 ${total} 条数据`}}</div>
|
||||||
|
<div class="filter-number" v-else></div>
|
||||||
|
<div>
|
||||||
<a-button class="operation-button" @click="emits('changeBatchProcessingModal',false)">关闭</a-button>
|
<a-button class="operation-button" @click="emits('changeBatchProcessingModal',false)">关闭</a-button>
|
||||||
<a-button type="primary" class="operation-button" @click="nextStep">下一步</a-button>
|
<a-button type="primary" class="operation-button" @click="nextStep">下一步</a-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<a-modal
|
<a-modal
|
||||||
v-model:open="submitModal"
|
v-model:open="submitModal"
|
||||||
title="内容替换"
|
title="内容替换"
|
||||||
|
|
@ -114,6 +126,9 @@ const singleField = ref('')
|
||||||
const oldValue = ref('')
|
const oldValue = ref('')
|
||||||
const newValue = ref('')
|
const newValue = ref('')
|
||||||
const submitLoading = ref(false)
|
const submitLoading = ref(false)
|
||||||
|
const total = ref()
|
||||||
|
const getTotalInteval = ref()
|
||||||
|
const showCancel = ref<number | null>(null)
|
||||||
const columns = computed(() => {
|
const columns = computed(() => {
|
||||||
return props.tableColumn.map(item => {
|
return props.tableColumn.map(item => {
|
||||||
return {
|
return {
|
||||||
|
|
@ -189,6 +204,23 @@ const submit = () => {
|
||||||
})
|
})
|
||||||
console.log('params',params)
|
console.log('params',params)
|
||||||
}
|
}
|
||||||
|
const getFilterNumber = () => {
|
||||||
|
if (getTotalInteval.value) clearTimeout(getTotalInteval.value);
|
||||||
|
getTotalInteval.value = setTimeout(() => {
|
||||||
|
let params = {
|
||||||
|
tableName: props.tableName,
|
||||||
|
filter: filterList.value,
|
||||||
|
field: props.tableColumn.map(item => item.value)
|
||||||
|
}
|
||||||
|
GetDataList(params).then(res => {
|
||||||
|
total.value = res.total
|
||||||
|
})
|
||||||
|
},1000)
|
||||||
|
}
|
||||||
|
const cancelFilterItem = (index) => {
|
||||||
|
filterList.value.splice(index, 1);
|
||||||
|
showCancel.value = null
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
@ -274,6 +306,7 @@ const submit = () => {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.filter-item-title:last-child{
|
.filter-item-title:last-child{
|
||||||
|
|
@ -347,7 +380,14 @@ const submit = () => {
|
||||||
height: 60px;
|
height: 60px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: end;
|
justify-content: space-between;
|
||||||
|
.filter-number{
|
||||||
|
font-family: PingFangSC-Regular;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #1E1E20;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
.operation-button{
|
.operation-button{
|
||||||
width: 169px;
|
width: 169px;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,14 @@
|
||||||
<div class="filter-title">
|
<div class="filter-title">
|
||||||
<div class="filter-item-title" style="position: relative;">
|
<div class="filter-item-title" style="position: relative;">
|
||||||
字段
|
字段
|
||||||
<div class="mark">{{ `条件${index+1}` }}</div>
|
<div
|
||||||
|
class="mark"
|
||||||
|
@mouseenter="showCancel = index"
|
||||||
|
@mouseleave="showCancel = null"
|
||||||
|
@click="cancelFilterItem(index)"
|
||||||
|
>
|
||||||
|
{{ showCancel == index? `取消`: `条件${index+1}` }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-item-title">类型</div>
|
<div class="filter-item-title">类型</div>
|
||||||
<div class="filter-item-title">条件</div>
|
<div class="filter-item-title">条件</div>
|
||||||
|
|
@ -24,6 +31,7 @@
|
||||||
:options="props.tableColumn"
|
:options="props.tableColumn"
|
||||||
style="width: 190px;height: 43px;"
|
style="width: 190px;height: 43px;"
|
||||||
placeholder="请选择相关字段"
|
placeholder="请选择相关字段"
|
||||||
|
@change="getFilterNumber"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-item-value">{{ getTableColumnType(item.field,item) }}</div>
|
<div class="filter-item-value">{{ getTableColumnType(item.field,item) }}</div>
|
||||||
|
|
@ -34,10 +42,11 @@
|
||||||
:options="item.type == 'numeric'? numberOptions: stringOptions"
|
:options="item.type == 'numeric'? numberOptions: stringOptions"
|
||||||
style="width: 190px;height: 43px;"
|
style="width: 190px;height: 43px;"
|
||||||
placeholder="请选择相关条件"
|
placeholder="请选择相关条件"
|
||||||
|
@change="getFilterNumber"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-item-value">
|
<div class="filter-item-value">
|
||||||
<a-input v-model:value="item.value" placeholder="请输入相关内容" style="width: 300px;height: 43px;" />
|
<a-input v-model:value="item.value" placeholder="请输入相关内容" style="width: 300px;height: 43px;" @change="getFilterNumber"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -50,10 +59,14 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
|
<div class="filter-number" v-if="total">{{`共 ${total} 条数据`}}</div>
|
||||||
|
<div class="filter-number" v-else></div>
|
||||||
|
<div>
|
||||||
<a-button class="operation-button" @click="emits('changeBatchProcessingModal',false)">关闭</a-button>
|
<a-button class="operation-button" @click="emits('changeBatchProcessingModal',false)">关闭</a-button>
|
||||||
<a-button type="primary" class="operation-button" @click="firstSubmit">导出</a-button>
|
<a-button type="primary" class="operation-button" @click="firstSubmit">导出</a-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<a-modal
|
<a-modal
|
||||||
v-model:open="submitModal"
|
v-model:open="submitModal"
|
||||||
title="选择字段"
|
title="选择字段"
|
||||||
|
|
@ -81,6 +94,7 @@ import { PlusOutlined } from '@ant-design/icons-vue';
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { getAppEnvConfig } from '@/utils/env';
|
import { getAppEnvConfig } from '@/utils/env';
|
||||||
import { numberOptions, stringOptions } from '@/views/demo/layer/BatchProcessingModal/util'
|
import { numberOptions, stringOptions } from '@/views/demo/layer/BatchProcessingModal/util'
|
||||||
|
import { GetDataList } from '@/api/demo/BatchProcessingModal'
|
||||||
|
|
||||||
const { VITE_GLOB_API_URL } = getAppEnvConfig();
|
const { VITE_GLOB_API_URL } = getAppEnvConfig();
|
||||||
const selectType = ref(0)
|
const selectType = ref(0)
|
||||||
|
|
@ -92,6 +106,9 @@ const props = defineProps(['tableColumn','tableName'])
|
||||||
const emits = defineEmits(['changeBatchProcessingModal'])
|
const emits = defineEmits(['changeBatchProcessingModal'])
|
||||||
const sqlValue = ref('')
|
const sqlValue = ref('')
|
||||||
const filterList:any = ref([])
|
const filterList:any = ref([])
|
||||||
|
const total = ref()
|
||||||
|
const getTotalInteval = ref()
|
||||||
|
const showCancel = ref<number | null>(null)
|
||||||
const firstSubmit = () => {
|
const firstSubmit = () => {
|
||||||
console.log('filterList',filterList)
|
console.log('filterList',filterList)
|
||||||
submitModal.value = true
|
submitModal.value = true
|
||||||
|
|
@ -170,6 +187,23 @@ const exportFile = (type) => {
|
||||||
submitModal.value = false
|
submitModal.value = false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
const getFilterNumber = () => {
|
||||||
|
if (getTotalInteval.value) clearTimeout(getTotalInteval.value);
|
||||||
|
getTotalInteval.value = setTimeout(() => {
|
||||||
|
let params = {
|
||||||
|
tableName: props.tableName,
|
||||||
|
filter: filterList.value,
|
||||||
|
field: props.tableColumn.map(item => item.value)
|
||||||
|
}
|
||||||
|
GetDataList(params).then(res => {
|
||||||
|
total.value = res.total
|
||||||
|
})
|
||||||
|
},1000)
|
||||||
|
}
|
||||||
|
const cancelFilterItem = (index) => {
|
||||||
|
filterList.value.splice(index, 1);
|
||||||
|
showCancel.value = null
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
@ -255,6 +289,7 @@ const exportFile = (type) => {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.filter-item-title:last-child{
|
.filter-item-title:last-child{
|
||||||
|
|
@ -323,7 +358,14 @@ const exportFile = (type) => {
|
||||||
height: 60px;
|
height: 60px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: end;
|
justify-content: space-between;
|
||||||
|
.filter-number{
|
||||||
|
font-family: PingFangSC-Regular;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #1E1E20;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
.operation-button{
|
.operation-button{
|
||||||
width: 169px;
|
width: 169px;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
setModalProps({ confirmLoading: false });
|
setModalProps({ confirmLoading: false });
|
||||||
});
|
});
|
||||||
const downloadFile = (type) => {
|
const downloadFile = (type) => {
|
||||||
const fileName = type == 0 ? 'Excel模板' : 'Shp模板';
|
const fileName = type == 0 ? 'Excel模板.xls' : 'Shp模板.zip';
|
||||||
const params = {
|
const params = {
|
||||||
type,
|
type,
|
||||||
tableName: props.tableName,
|
tableName: props.tableName,
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,14 @@
|
||||||
/>
|
/>
|
||||||
<a-button type="primary" @click="getList"> 查询 </a-button>
|
<a-button type="primary" @click="getList"> 查询 </a-button>
|
||||||
<a-button type="primary" @click="exportTemplate"> 导出模版 </a-button>
|
<a-button type="primary" @click="exportTemplate"> 导出模版 </a-button>
|
||||||
<a-button type="primary" @click="handleItem"> 数据导入 </a-button>
|
<a-upload
|
||||||
|
:accept="'.xlsx,.csv,.xls,.zip'"
|
||||||
|
:showUploadList="false"
|
||||||
|
:custom-request="customRequest"
|
||||||
|
style="margin-right: 0px;"
|
||||||
|
>
|
||||||
|
<a-button type="primary"> 数据导入 </a-button>
|
||||||
|
</a-upload>
|
||||||
<a-button type="primary" @click="changeBatchProcessingModal(true)"> 批量操作 </a-button>
|
<a-button type="primary" @click="changeBatchProcessingModal(true)"> 批量操作 </a-button>
|
||||||
<a-button type="primary" @click="styleHandle"> 样式配置 </a-button>
|
<a-button type="primary" @click="styleHandle"> 样式配置 </a-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -163,6 +170,8 @@
|
||||||
import { uploadFile, fun_Delete } from '@/api/demo/files';
|
import { uploadFile, fun_Delete } from '@/api/demo/files';
|
||||||
import { getAppEnvConfig } from '@/utils/env';
|
import { getAppEnvConfig } from '@/utils/env';
|
||||||
import BatchProcessingModal from './BatchProcessingModal/index.vue';
|
import BatchProcessingModal from './BatchProcessingModal/index.vue';
|
||||||
|
import { Upload, UploadShape, UploadExcelAll } from '@/api/demo/BatchProcessingModal'
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
|
||||||
const { VITE_GLOB_API_URL } = getAppEnvConfig();
|
const { VITE_GLOB_API_URL } = getAppEnvConfig();
|
||||||
const { createConfirm, createMessage } = useMessage();
|
const { createConfirm, createMessage } = useMessage();
|
||||||
|
|
@ -432,6 +441,35 @@
|
||||||
openTempeleteModel(true);
|
openTempeleteModel(true);
|
||||||
};
|
};
|
||||||
onMounted(() => {});
|
onMounted(() => {});
|
||||||
|
const customRequest = (file) => {
|
||||||
|
console.log('handleCustomRequest',file)
|
||||||
|
const name = file.file.name.toLowerCase();
|
||||||
|
if (name.endsWith('.zip')){
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('files', file.file)
|
||||||
|
Upload(formData).then(res => {
|
||||||
|
console.log(res)
|
||||||
|
const filePath = res[0].filePath
|
||||||
|
let params = {
|
||||||
|
tableName: tableName.value,
|
||||||
|
zipFilePath: filePath
|
||||||
|
}
|
||||||
|
UploadShape(params).then(result => {
|
||||||
|
message.success('导入成功')
|
||||||
|
reload()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('file', file.file)
|
||||||
|
UploadExcelAll({File: formData, tableName: tableName.value}).then(res => {
|
||||||
|
message.success('导入成功')
|
||||||
|
reload()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// procedure.value ++
|
||||||
|
return false
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue