LinYeFangHuo/src/packages/components/Zhigan/Zhigan/ZhiGan_SheXiangTouModal/index.vue

796 lines
24 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="ZhiGan_SheXiangTouModal">
<div class="modalCloseloseButton">
<CloseButton :dataStyle="option.dataStyle" @click="hideModal" />
</div>
<div class="modalTitleName">
<span>摄像头监控列表</span>
</div>
<div class="modalTitleButton">
<TypeButton
:typeName="'监控画面X1'"
:thisType="'1'"
:nowType="option.dataStyle.nowType"
:dataStyle="option.dataStyle"
@click="option.dataStyle.nowType = '1'"
/>
<TypeButton
:typeName="'监控画面X4'"
:thisType="'4'"
:nowType="option.dataStyle.nowType"
:dataStyle="option.dataStyle"
@click="option.dataStyle.nowType = '4'"
/>
<TypeButton
:typeName="'监控画面X9'"
:thisType="'9'"
:nowType="option.dataStyle.nowType"
:dataStyle="option.dataStyle"
@click="option.dataStyle.nowType = '9'"
/>
</div>
<div class="mainBodyDiv">
<div class="leftDiv">
<div class="leftDivTitle">
<LeftTitleIcon1 :dataStyle="option.dataStyle" />
<div class="leftDivSelect">
<n-select
v-model:value="selectLabel"
:options="option.dataset"
label-field="label"
value-field="label"
/>
</div>
</div>
<div class="leftDivSearch">
<n-input-group>
<div class="search-input" :style="{ width: '70%' }">
<n-input v-model:value="searchValue" placeholder="请输入搜索关键字" />
</div>
<n-button type="primary" class="search-button" @click="searchDataList"> </n-button>
</n-input-group>
</div>
<div class="leftDivVideoList">
<div
class="leftDivVideoListItem"
v-for="(item, index) in dataListAfterSearch"
:key="index"
@click="clickListVideo(item)"
>
<div class="leftDivVideoListIcon">
<ListVideoNameIcon :dataStyle="option.dataStyle" />
</div>
<div class="leftDivVideoListIcontitle">
<span>{{ item.name }}</span>
</div>
</div>
</div>
</div>
<div class="rightDiv">
<div
class="rightVideoItem"
v-for="(videoItem, videoIndex) in option.videoList"
:key="videoIndex"
@click="changeThisVideoIfIsNum(videoIndex)"
>
<div class="rightVideoItemTitle" v-if="isEdit">
<span
:style="{
color: option.dataStyle.videoTitleFontColor,
fontSize: option.dataStyle.videoTitleFontSize + 'px',
}"
>
{{ videoItem.title ? videoItem.title : '视频标题' }}
</span>
</div>
<div class="rightVideoItemCloseButton" v-if="isEdit">
<Close
:style="{
width: option.dataStyle.closeVideoIconWidthAndHeight + 'px',
height: option.dataStyle.closeVideoIconWidthAndHeight + 'px',
fontSize: option.dataStyle.closeVideoIconWidthAndHeight + 'px',
color: option.dataStyle.closeVideoIconColor,
}"
/>
</div>
<div :class="changeThisNum == videoIndex ? 'rightVideoItemDiv2' : 'rightVideoItemDiv'">
<img
v-if="isEdit || !videoItem.videourl"
:width="videoWidthNoPadding"
:height="videoHeightNoPadding"
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
preview-disabled
/>
<MonitorHK
:ref="(el) => setMonitorRef(el, videoIndex)"
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '海康'"
:index="videoIndex"
:serialNumberValue="videoItem.videourl"
:width="videoWidthNoPadding"
:height="videoHeightNoPadding"
:timestamp="option.dataStyle.timestamp"
:dataStyle="option.dataStyle"
@changeThisVideo="changeThisVideo"
@closeThisVideo="closeThisVideo"
/>
<MonitorLC
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"
@hideHKVideo="hideHKVideo"
@showHKVideo="showHKVideo"
/>
<MonitorTX
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '腾讯'"
:title="videoItem.title"
:videourl="videoItem.videourl"
:index="videoIndex"
:width="videoWidthNoPadding"
:height="videoHeightNoPadding"
:timestamp="option.dataStyle.timestamp"
:dataStyle="option.dataStyle"
@changeThisVideo="changeThisVideo"
@closeThisVideo="closeThisVideo"
@hideHKVideo="hideHKVideo"
@showHKVideo="showHKVideo"
/>
<MonitorQX
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '青犀'"
:title="videoItem.title"
:videourl="videoItem.videourl"
:index="videoIndex"
:width="videoWidthNoPadding"
:height="videoHeightNoPadding"
:dataStyle="option.dataStyle"
@changeThisVideo="changeThisVideo"
@closeThisVideo="closeThisVideo"
@hideHKVideo="hideHKVideo"
@showHKVideo="showHKVideo"
/>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {
PropType,
toRefs,
watch,
reactive,
ref,
computed,
onMounted,
onBeforeUnmount,
} from 'vue';
import { CreateComponentType } from '@/packages/index.d';
import { icon } from '@/plugins';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { useChartDataFetch } from '@/hooks';
import { useMessage } from '@/hooks/web/useMessage';
import { cloneDeep } from 'lodash-es';
import dayjs from 'dayjs';
import { EventBus } from '@/utils/eventBus';
import { replaceSqlParams } from '@/utils/sqlHandler';
import { Close } from '@vicons/ionicons5';
import {
CloseButton,
TypeButton,
LeftTitleIcon1,
LeftTitleIcon2,
ListVideoNameIcon,
} from './svg/index';
import { MonitorHK, MonitorLC, MonitorTX, MonitorQX } from './video/index';
import Axios from 'axios';
import { getAppEnvConfig } from '@/utils/env'
var { VITE_GLOB_API_URL } = getAppEnvConfig();
const { createMessage } = useMessage();
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true,
},
});
const { w, h } = toRefs(props.chartConfig.attr);
const option = reactive({
dataset: props.chartConfig.option.dataset,
dataStyle: props.chartConfig.option.dataStyle,
videoList: props.chartConfig.option.videoList,
status: props.chartConfig.status,
});
// 是否是编辑状态
const isEdit = window.location.href.includes('/chart/home/');
// 下拉
const selectLabel = ref(option.dataset[0].label);
// 搜索
const searchValue = ref('');
async function getMonitorList(){
const querys = {
page:1,
limit:999
};
return Axios({
method: "get",
url: VITE_GLOB_API_URL + '/api/FireManagement/GetCameraInfoPageList',
params: querys,
headers: {
'X-Token': localStorage.getItem("X-Token")
}
})
}
const dataListAfterSearch = ref(option.dataset[0].value);
getMonitorList().then(res=>{
dataListAfterSearch.value = res.data.result.items;
})
function searchDataList() {
let selectData = option.dataset.find((f) => f.label == selectLabel.value).value;
if (searchValue.value.trim()) {
dataListAfterSearch.value = selectData.filter((item) => {
return item.title.includes(searchValue.value);
});
} else {
dataListAfterSearch.value = selectData;
}
}
// 视频宽高
const videoWidthNoPadding = ref(
option.dataStyle.videoWidth - (20 / Math.sqrt(parseInt(option.dataStyle.nowType))) * 2,
);
const videoHeightNoPadding = ref(
option.dataStyle.videoHeight - (20 / Math.sqrt(parseInt(option.dataStyle.nowType))) * 2,
);
watch(
() => option.dataStyle.nowType,
(newValue, oldValue) => {
// 高度
option.dataStyle.videoHeight =
h.value -
option.dataStyle.mainBodyMarginTop -
option.dataStyle.leftListMarginTop -
(h.value * 125) / 838;
if (newValue == '1') {
option.dataStyle.videoHeight = option.dataStyle.videoHeight;
}
if (newValue == '4') {
option.dataStyle.videoHeight = (option.dataStyle.videoHeight - 10) / 2;
}
if (newValue == '9') {
option.dataStyle.videoHeight = (option.dataStyle.videoHeight - 20) / 3;
}
videoHeightNoPadding.value =
option.dataStyle.videoHeight - (20 / Math.sqrt(parseInt(option.dataStyle.nowType))) * 2;
// 宽度
option.dataStyle.videoWidth =
w.value -
option.dataStyle.mainLeftMarginLeft1 -
((w.value * 1315) / 1360) * 0.25 -
option.dataStyle.mainLeftMarginLeft2 -
option.dataStyle.mainLeftMarginLeft3 -
(w.value * 45) / 1360;
if (newValue == '1') {
option.dataStyle.videoWidth = option.dataStyle.videoWidth;
}
if (newValue == '4') {
option.dataStyle.videoWidth = (option.dataStyle.videoWidth - 10) / 2;
}
if (newValue == '9') {
option.dataStyle.videoWidth = (option.dataStyle.videoWidth - 20) / 3;
}
videoWidthNoPadding.value =
option.dataStyle.videoWidth - (20 / Math.sqrt(parseInt(option.dataStyle.nowType))) * 2;
// 监控画面X1
if (newValue == '1') {
option.dataStyle.proportion = 100;
let temp = cloneDeep(option.videoList);
option.videoList = [temp[0]];
if (oldValue == '9') {
}
}
// 监控画面X4
if (newValue == '4') {
option.dataStyle.proportion = 49;
if (oldValue == '1') {
let temp = cloneDeep(option.videoList);
option.videoList = [temp[0], {}, {}, {}];
}
if (oldValue == '9') {
let temp = cloneDeep(option.videoList);
option.videoList = [temp[0], temp[1], temp[2], temp[3]];
}
}
// 监控画面X9
if (newValue == '9') {
if (oldValue == '1') {
let temp = cloneDeep(option.videoList);
option.videoList = [temp[0], {}, {}, {}, {}, {}, {}, {}, {}];
}
if (oldValue == '4') {
let temp = cloneDeep(option.videoList);
option.videoList = [temp[0], temp[1], temp[2], temp[3], {}, {}, {}, {}, {}];
}
}
},
);
// 点击标题播放此视频
const changeThisFlag = ref(false);
const changeThisNum = ref(9);
// 指定修改视频
function changeThisVideo(videoIndex) {
if (videoIndex == changeThisNum.value) {
changeThisNum.value = 9;
changeThisFlag.value = false;
} else {
changeThisNum.value = videoIndex;
changeThisFlag.value = true;
}
}
// 点击-修改指定的空视频
function changeThisVideoIfIsNum(videoIndex) {
if (!option.videoList[videoIndex].videourl) {
if (changeThisNum.value == videoIndex) {
changeThisNum.value = 9;
changeThisFlag.value = false;
} else {
changeThisNum.value = videoIndex;
changeThisFlag.value = true;
}
}
}
// 隐藏弹窗
function hideModal() {
option.status.hide = true;
switch (option.dataStyle.nowType) {
case '1':
option.videoList = [{}];
break;
case '4':
option.videoList = [{}, {}, {}, {}];
break;
case '9':
option.videoList = [{}, {}, {}, {}, {}, {}, {}, {}, {}];
break;
}
}
// 修改视频
function clickListVideo(item) {
console.log("item123",item);
// 不显示已有视频
if (
option.videoList.some((li: any) => li.title == item.name) &&
option.videoList.some((li: any) => li.videourl == item.videourl)
) {
createMessage.warning('点击的视频【' + item.title + '】已展示!');
return;
}
// 指定修改视频
if (changeThisFlag.value) {
option.videoList[cloneDeep(changeThisNum.value)] = item;
changeThisNum.value = 9;
changeThisFlag.value = false;
return;
}
// 先修改为空的
let flag = true;
let num = 0;
option.videoList.forEach((li, index) => {
if (!li.videourl && flag) {
option.videoList[index] = item;
flag = false;
}
});
// 全不为空时,按顺序修改
if (flag) {
option.videoList[num] = item;
num++;
}
if (num == option.videoList.length) {
num = 0;
}
}
// 关闭当前视频
function closeThisVideo(index) {
if (index < option.videoList.length) {
option.videoList[index] = {};
}
}
// 其他视频组件全屏,隐藏海康视频组件
const monitorRefs: any = ref([]);
let monitorHKList: any = [];
function setMonitorRef(el, index) {
monitorHKList.push(index);
monitorHKList = [...new Set(monitorHKList)];
monitorRefs.value[index] = el;
}
// 隐藏海康视频组件
function hideHKVideo() {
monitorHKList.forEach((index) => {
if (monitorRefs.value[index]?.hideHkVideo) {
monitorRefs.value[index].hideHkVideo();
}
});
}
// 展示被隐藏的海康视频组件
function showHKVideo() {
monitorHKList.forEach((index) => {
if (monitorRefs.value[index]?.hideHkVideo) {
monitorRefs.value[index].showHkVideo();
}
});
}
// 初始化视频控件
onMounted(() => {
// 用于规避视频id重复
if (!option.dataStyle.timestamp) {
option.dataStyle.timestamp = dayjs().unix();
}
// 组件通信
const sql = props.chartConfig.request?.requestSQLContent?.sql;
EventBus.on(props.chartConfig.id + 'dataupdate', (data) => {
props.chartConfig.request.requestSQLContent.sql = replaceSqlParams(sql, { Id: data.id });
// 数据callback处理预览时触发
useChartDataFetch(props.chartConfig, useChartEditStore, (resData: any[]) => {
option.dataset = resData;
});
});
});
// 数据callback处理预览时触发
// 显示+非编辑状态下运行
watch(
() => option.status.hide,
(newValue) => {
if (!newValue && !isEdit) {
// 数据callback处理预览时触发
useChartDataFetch(props.chartConfig, useChartEditStore, (resData: any[]) => {
if (resData) {
option.dataset = resData;
}
});
}
},
);
watch(
() => option.dataStyle.closeButtonWidth,
() => {
option.dataStyle.closeButtonHeight = (option.dataStyle.closeButtonWidth / 52) * 30;
},
);
watch(
() => option.dataStyle.typeButtonWidth,
() => {
option.dataStyle.typeButtonHeight = (option.dataStyle.closeButtonWidth / 115) * 32;
},
);
watch(
() => option.dataStyle.leftTitleIcon2_Width,
() => {
option.dataStyle.leftTitleIcon2_Height = (option.dataStyle.closeButtonWidth / 15) * 12;
},
);
watch(
() => option.dataStyle.leftDivVideoListIconWidth,
() => {
option.dataStyle.leftDivVideoListIconHeight =
(option.dataStyle.leftDivVideoListIconWidth / 23) * 16;
},
);
</script>
<style lang="scss" scoped>
.ZhiGan_SheXiangTouModal {
width: v-bind('`${w}px`');
height: v-bind('`${h}px`');
// 页面不能被选中
-webkit-user-select: none; /* Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE/Edge */
user-select: none;
background-image: url('@/assets/images/chart/zhigan/component/SheXiangTouModal_Back.png');
background-size: 100% 100%;
position: relative;
}
.modalCloseloseButton {
position: absolute;
top: 1%;
right: 1%;
}
.modalTitleName {
position: absolute;
top: v-bind('`${ 3 * h / 838}%`');
left: v-bind('`${ 7 * w / 1360}%`');
span {
font-family:
PingFangSC,
PingFang SC;
font-weight: 900;
font-size: v-bind('`${ option.dataStyle.generalTitleFontSize }px`');
color: v-bind('`${option.dataStyle.generalTitleFontColor}`');
text-shadow: 0px 0px 13px v-bind('`${option.dataStyle.generalTitleFontShadow}`');
text-align: left;
font-style: normal;
}
}
.modalTitleButton {
position: absolute;
top: v-bind('`${ 3.5 * h / 838}%`');
left: v-bind('`${ 27 * w / 1360}%`');
display: inline-flex;
}
// 主体
.mainBodyDiv {
padding-top: v-bind('`${h*75/838}px`');
padding-bottom: v-bind('`${h*50/838}px`');
height: 1v-bind('`${h-h*125/838}px`');
padding-left: v-bind('`${w*25/1360}px`');
padding-right: v-bind('`${w*20/1360}px`');
width: v-bind('`${w*1360/1360}px`');
display: flex;
// 左侧
.leftDiv {
width: v-bind('`${(w*1315/1360) * 0.25}px`');
height: v-bind('`${h-h*125/838}px`');
margin-top: v-bind('`${option.dataStyle.mainBodyMarginTop}px`');
margin-left: v-bind('`${option.dataStyle.mainLeftMarginLeft1}px`');
// 标题
.leftDivTitle {
display: inline-flex;
height: v-bind('`${option.dataStyle.leftTitleIcon1_WidthAndHeight}px`');
.leftDivTitleSpan {
margin-left: 5px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 900;
font-size: v-bind('`${ option.dataStyle.leftTitle_FontSize }px`');
color: v-bind('`${option.dataStyle.leftTitle_FontColor}`');
text-shadow: 0px 0px 13px v-bind('`${option.dataStyle.leftTitle_FontShadow}`');
text-align: left;
font-style: normal;
}
.leftDivSelect {
height: v-bind('`${option.dataStyle.leftTitleIcon1_WidthAndHeight}px`');
width: v-bind(
'`${(w*1315/1360) * 0.25 - option.dataStyle.leftTitleIcon1_WidthAndHeight}px`'
);
display: flex;
align-items: center;
justify-content: center;
}
}
// 查询
.leftDivSearch {
margin-top: v-bind('`${option.dataStyle.leftSearchMarginTop}px`');
margin-left: v-bind('`${option.dataStyle.leftSearchMarginLeft}px`');
width: 100%;
.search-button {
background: linear-gradient(95deg, #00c16b 0%, #008e39 100%), #000000;
border-radius: 3px;
}
}
// 列表
.leftDivVideoList {
margin-top: v-bind('`${option.dataStyle.leftListMarginTop}px`');
margin-left: v-bind('`${option.dataStyle.leftListMarginLeft}px`');
overflow-y: auto;
display: inline-block;
height: v-bind('`${option.dataStyle.leftListHeight}px`');
.leftDivVideoListItem {
display: inline-flex;
width: v-bind('`${option.dataStyle.leftListWidth}px`');
height: v-bind('`${option.dataStyle.leftListAloneHeight}px`');
background: v-bind('`${option.dataStyle.leftListFontBackgroud}`');
.leftDivVideoListIcon {
width: v-bind('`${option.dataStyle.leftListWidth_Icon}px`');
height: v-bind('`${option.dataStyle.leftListAloneHeight}px`');
display: flex;
align-items: center;
justify-content: center;
background: #15251c;
border-bottom: 2px solid #3baf64;
}
.leftDivVideoListIcontitle {
width: v-bind('`${option.dataStyle.leftListWidth_Title}px`');
height: v-bind('`${option.dataStyle.leftListAloneHeight}px`');
background: #15251c;
border-bottom: 2px solid #3baf64;
span {
height: v-bind('`${option.dataStyle.leftListAloneHeight}px`');
margin-left: 15px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
font-size: v-bind('`${option.dataStyle.leftListFontSize}px`');
color: v-bind('`${option.dataStyle.leftListFontColor}`');
line-height: v-bind('`${option.dataStyle.leftListAloneHeight}px`');
text-align: left;
justify-content: center;
font-style: normal;
text-transform: uppercase;
}
}
}
}
.leftDivVideoList::-webkit-scrollbar {
display: none;
}
.leftDivVideoList {
scrollbar-width: none;
-ms-overflow-style: none;
}
}
// select样式设置
::v-deep .n-base-selection {
--n-border: 0px solid #1e2421 !important;
}
::v-deep .n-base-selection--selected {
--n-border: 0px solid #1e2421 !important;
}
::v-deep .n-base-selection {
background: #ffffff00 !important;
}
::v-deep .n-base-selection-label {
background: #ffffff00 !important;
}
::v-deep .n-base-selection-input {
background: #ffffff00 !important;
border: 0px solid #1e2421 !important;
}
::v-deep .n-base-selection-input__content {
margin-left: 5px;
font-family:
PingFangSC,
PingFang SC;
font-weight: 900;
font-size: v-bind('`${ option.dataStyle.leftTitle_FontSize }px`');
color: v-bind('`${option.dataStyle.leftTitle_FontColor}`');
text-shadow: 0px 0px 13px v-bind('`${option.dataStyle.leftTitle_FontShadow}`');
text-align: left;
font-style: normal;
}
// 查询样式设置
::v-deep .n-input {
--n-border: 2px solid #18a058 !important;
}
::v-deep .n-input--resizable {
--n-border: 2px solid #18a058 !important;
}
::v-deep .n-input--stateful {
--n-border: 2px solid #18a058 !important;
}
// 右侧
.rightDiv {
width: v-bind('`${(w*1315/1360) * 0.75}px`');
height: v-bind('`${(h-h*125/838) * 0.92}px`');
margin-top: v-bind('`${option.dataStyle.mainBodyMarginTop}px`');
margin-left: v-bind('`${option.dataStyle.mainLeftMarginLeft2}px`');
margin-right: v-bind('`${option.dataStyle.mainLeftMarginLeft3}px`');
display: flex;
flex-wrap: wrap;
gap: 10px;
.rightVideoItem {
position: relative;
background-image: url('@/assets/images/chart/zhigan/component/SheXiangTouModal_VideoBack.png');
background-size: 100% 100%;
width: v-bind('`${option.dataStyle.videoWidth}px`');
height: v-bind('`${option.dataStyle.videoHeight}px`');
.rightVideoItemTitle {
position: absolute;
top: 6%;
left: 5%;
z-index: 100;
}
.rightVideoItemCloseButton {
position: absolute;
top: 6%;
right: 5%;
z-index: 100;
}
.rightVideoItemDiv {
width: 100%;
height: 100%;
padding: v-bind('`${20 / Math.sqrt(parseInt(option.dataStyle.nowType))}px`');
}
.rightVideoItemDiv2 {
width: 100%;
height: 100%;
padding: v-bind('`${14 / Math.sqrt(parseInt(option.dataStyle.nowType))}px`');
border: v-bind('`${6 / Math.sqrt(parseInt(option.dataStyle.nowType))}px`') solid #0fab3f;
}
}
}
}
::v-deep .search-input {
background-image: url('./svg/searchInput.svg') !important;
background-size: 100% 100% !important;
background-repeat: no-repeat !important;
}
::v-deep .n-input {
background: #ffffff00 !important;
color: #ffffff !important;
}
::v-deep .n-input__input-el {
color: #ffffff !important;
}
</style>