239 lines
5.5 KiB
Vue
Raw Normal View History

2025-05-22 16:24:05 +08:00
<template>
<view class="video-monitor">
<view class="channel_wrap">
<view class="item_body" v-for="(item, i) in channelList" :key="i"
@click="gotoDevicePlayer(item.deviceSipId, item.channelId, item.status)">
<view class="img">
<image src="@/static/common/cameras.png" mode="widthFix" style="width: 200rpx;" class="play-icon">
</image>
</view>
<view class="content">
<view class="left_content">
<u--text class="channel_name" :text="item.channelName"></u--text>
</view>
<view class="right_content">
<u--text class="device_info" :text="'@'+item.model"></u--text>
</view>
</view>
<view class="status">
<u-tag v-if="item.statusInfo" :type="item.statusInfo.type" :plain="true" size="mini"
:text="item.statusInfo.name"></u-tag>
</view>
</view>
</view>
<u-empty mode="data" :show="total === 0" marginTop="60" :text="$tt('scene.emptyData')"></u-empty>
</view>
</template>
<script>
import {
relateChannelList
} from '@/apis/modules/device.js';
import {
getSipStatusInfo
} from '@/helpers/common.js';
export default {
name: "videoMonitor",
props: {
device: {
type: Object,
default: null,
required: true
}
},
watch: {
// 兼容小程序
device: function (newVal, oldVal) {
this.deviceInfo = newVal;
this.isSubDev = newVal.subDeviceList && newVal.subDeviceList.length > 0;
if (this.deviceInfo.sipRelationList) {
this.getRelateChannelList();
}
}
},
data () {
return {
isSubDev: false,
// 设备信息
deviceInfo: {
chartList: [],
},
//通道列表
channelList: [],
// 设备通道
channelLoadStatus: 'nomore',
queryParams: {
deviceSipId: '', //设备sipid
},
total: 0,
};
},
created () {
// 获取设备状态(兼容H5和APP)
if (this.device.subDeviceList) {
this.deviceInfo = this.device;
this.isSubDev = this.device.subDeviceList.length > 0;
}
},
methods: {
// 设备通道
getRelateChannelList () {
return new Promise((resolve, reject) => {
relateChannelList(this.deviceInfo.deviceId).then(res => {
if (res.code === 200) {
this.channelList = res.data;
this.total = res.data.length;
res.data.map(item => {
item.statusInfo = getSipStatusInfo(item.status);
return item;
})
resolve(res.data);
}
}).catch(error => {
reject(error);
});
});
},
gotoDevicePlayer (deviceSipId, channelSipId, status) {
let statusInfo = getSipStatusInfo(status)
if (status !== 3) {
uni.showToast({
icon: 'none',
title: `无法查看${getSipStatusInfo(status).name}数据`
});
return;
}
// #ifdef H5
uni.$u.route('/pages_player/list/devicePlayer', {
deviceId: deviceSipId,
channelSipId: channelSipId,
});
//#endif
// #ifdef APP-PLUS
uni.$u.route('/pages_player/list/devicePlayerApp', {
deviceId: deviceSipId,
channelSipId: channelSipId,
});
//#endif
// #ifdef MP-WEIXIN
uni.showToast({
icon: 'none',
title: this.$tt('timing.nosupported')
});
//#endif
},
}
}
</script>
<style lang="scss" scoped>
.video-monitor {
padding: 20rpx;
.channel_wrap {
padding: 20rpx 0;
.item_body {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 30rpx;
background: rgba(255, 255, 255, 0.8); // 更轻的透明背景
border-radius: 32rpx;
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.1), inset 0 1rpx 1rpx rgba(255, 255, 255, 0.3); // 外部阴影+内部高光
backdrop-filter: blur(15rpx) saturate(180%); // 轻微模糊和饱和度提升
border: 1rpx solid rgba(255, 255, 255, 0.3); // 玻璃效果边框
transition: all 0.3s ease;
padding: 40rpx;
cursor: pointer;
overflow: hidden;
&:hover {
transform: translateY(-10rpx); // 悬停时轻微提升
background: rgba(255, 255, 255, 0.2); // 悬停时背景变得更透明
box-shadow: 0 16rpx 48rpx rgba(0, 0, 0, 0.2), inset 0 2rpx 2rpx rgba(255, 255, 255, 0.4); // 更强的阴影和高光
}
.img {
margin-top: 40rpx;
padding: 20rpx;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: linear-gradient(135deg, rgba(62, 135, 230, 0.3), rgba(0, 255, 255, 0.3)); // 渐变背景增强
border-radius: 20rpx;
margin-bottom: 30rpx;
position: relative;
overflow: hidden;
.play-icon {
transition: transform 0.3s ease;
}
&:hover .play-icon {
transform: scale(1.2); // 放大效果
}
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(circle, rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0));
opacity: 0;
transition: opacity 0.4s ease;
}
&:hover::before {
opacity: 1;
}
}
.content {
display: flex;
justify-content: space-between;
width: 100%;
padding: 0 30rpx;
.left_content {
.channel_name {
font-size: 34rpx;
font-weight: bold;
color: #333333;
text-align: left;
}
}
.right_content {
.device_info {
font-size: 28rpx;
color: #777777;
text-align: right;
}
}
}
.status {
position: absolute;
top: 20rpx;
right: 20rpx;
}
}
}
.channel_wrap .item_body {
transition: all 0.3s ease;
}
}
</style>