安卓视频监控插件更新,监控列表更新
parent
69b227ec7f
commit
45e8a49330
|
|
@ -0,0 +1,11 @@
|
|||
import request from '@/utils/request'
|
||||
import apiUrl from '@/utils/api'
|
||||
|
||||
// 根据用户ID查询门店列表
|
||||
export function listMonitorData(id) {
|
||||
return request({
|
||||
baseUrl: apiUrl,
|
||||
url: `/mall/device/getDevice/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name" : "海驰24",
|
||||
"appid" : "__UNI__F8B45C3",
|
||||
"appid" : "__UNI__7302921",
|
||||
"description" : "111",
|
||||
"versionName" : "1.2.6",
|
||||
"versionCode" : 106,
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -38,26 +38,33 @@
|
|||
<view class="setting-row">
|
||||
<text class="setting-label">设备类型:</text>
|
||||
<view class="options-group">
|
||||
<text class="option-btn" :class="!isNvr ? 'active-btn' : ''" @click="changeNvr(false)">单体(IPC)</text>
|
||||
<text class="option-btn" :class="isNvr ? 'active-btn' : ''" @click="changeNvr(true)">主机(NVR)</text>
|
||||
<text class="option-btn" v-if="!isNvr" :class="!isNvr ? 'active-btn' : ''" @click="changeNvr(false)">单体(IPC)</text>
|
||||
<text class="option-btn" v-else :class="isNvr ? 'active-btn' : ''" @click="changeNvr(true)">主机(NVR)</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="setting-row" v-if="isNvr">
|
||||
<view class="setting-row" v-if="isNvr && totalChannel > 0">
|
||||
<text class="setting-label">通道:</text>
|
||||
<view class="options-group">
|
||||
<text class="option-btn" :class="currentChannel === 0 ? 'active-btn' : ''" @click="changeChannel(0)">CH1</text>
|
||||
<text class="option-btn" :class="currentChannel === 1 ? 'active-btn' : ''" @click="changeChannel(1)">CH2</text>
|
||||
<text class="option-btn" :class="currentChannel === 2 ? 'active-btn' : ''" @click="changeChannel(2)">CH3</text>
|
||||
<text class="option-btn" :class="currentChannel === 3 ? 'active-btn' : ''" @click="changeChannel(3)">CH4</text>
|
||||
</view>
|
||||
<!-- nvue 的 flex 默认不支持换行(flex-wrap),通道多的话外面套一个 scroll-view 可以左右滑动 -->
|
||||
<scroll-view class="channel-scroll" scroll-x="true" show-scrollbar="false">
|
||||
<view class="options-group channel-group">
|
||||
<text
|
||||
class="option-btn"
|
||||
v-for="(item, index) in totalChannel"
|
||||
:key="index"
|
||||
:class="currentChannel === index ? 'active-btn' : ''"
|
||||
@click="changeChannel(index)">
|
||||
CH{{ index + 1 }}
|
||||
</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<view class="setting-row">
|
||||
<text class="setting-label">清晰度:</text>
|
||||
<view class="options-group">
|
||||
<text class="option-btn" :class="currentStreamType === 1 ? 'active-btn' : ''" @click="changeStream(1)">高清</text>
|
||||
<text class="option-btn" :class="currentStreamType === 2 ? 'active-btn' : ''" @click="changeStream(2)">标清</text>
|
||||
<!-- <text class="option-btn" :class="currentStreamType === 0 ? 'active-btn' : ''" @click="changeStream(0)">高清</text> -->
|
||||
<text class="option-btn" :class="currentStreamType === 1 ? 'active-btn' : ''" @click="changeStream(1)">标清</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -77,12 +84,13 @@
|
|||
export default {
|
||||
data() {
|
||||
return {
|
||||
deviceUid: 'HLTY036190SYNSK', // 默认使用你 Demo 里的测试 UID
|
||||
deviceUid: '', // 默认使用你 Demo 里的测试 UID
|
||||
isPlaying: false,
|
||||
isRecording: false, // 是否正在录像
|
||||
statusMsg: '等待操作',
|
||||
currentChannel: 0, // 0对应CH1, 1对应CH2...
|
||||
currentStreamType: 1, // 1为高清(主码流),2为标清(子码流)
|
||||
totalChannel: 1, // 设备的总通道数,默认为1,由上个页面传过来
|
||||
currentStreamType: 1, // 0为高清(主码流),1为标清(子码流)
|
||||
isNvr: true // 是否为 NVR 设备
|
||||
}
|
||||
},
|
||||
|
|
@ -90,10 +98,18 @@
|
|||
if (options && options.uid) {
|
||||
this.deviceUid = options.uid;
|
||||
}
|
||||
// 接收总通道数
|
||||
if (options && options.channel) {
|
||||
this.totalChannel = parseInt(options.channel);
|
||||
// 如果通道数不合理(比如0或者NaN),给个默认值
|
||||
if (!this.totalChannel || this.totalChannel <= 0) {
|
||||
this.totalChannel = 1;
|
||||
}
|
||||
}
|
||||
// 如果上个页面传了 isNvr 参数,这里可以接收
|
||||
if (options && typeof options.isNvr !== 'undefined') {
|
||||
// options.isNvr 通常传过来是字符串 'true' 或 'false'
|
||||
this.isNvr = options.isNvr === 'true';
|
||||
this.isNvr = options.isNvr;
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
|
|
@ -373,6 +389,14 @@
|
|||
flex-direction: row;
|
||||
flex: 1;
|
||||
}
|
||||
.channel-scroll {
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
}
|
||||
.channel-group {
|
||||
flex-direction: row;
|
||||
padding-bottom: 10rpx; /* 预留一点底部空间,防止被遮挡 */
|
||||
}
|
||||
.option-btn {
|
||||
padding: 10rpx 20rpx;
|
||||
font-size: 26rpx;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,227 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<!-- <view class="header">
|
||||
<text class="title">监控设备列表</text>
|
||||
</view> -->
|
||||
|
||||
<scroll-view class="list-container" scroll-y>
|
||||
<!-- 设备列表循环 -->
|
||||
<view class="device-card" v-for="(item, index) in deviceList" :key="index" @click="goToMonitorDetail(item)">
|
||||
<view class="device-info">
|
||||
<text class="device-name">{{ item.name }}</text>
|
||||
<text class="device-uid">UID: {{ item.uid }}</text>
|
||||
<!-- <view class="device-status">
|
||||
<text class="status-dot" :class="item.online ? 'online' : 'offline'"></text>
|
||||
<text class="status-text">{{ item.online ? '在线' : '离线' }}</text>
|
||||
</view> -->
|
||||
</view>
|
||||
|
||||
<view class="device-action">
|
||||
<text class="action-text">{{ pageType === '0' ? '查看回放' : '查看监控' }}</text>
|
||||
<uni-icons type="right" size="16" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 无数据提示 -->
|
||||
<view class="empty-tips" v-if="deviceList.length === 0">
|
||||
<text class="empty-text">暂无监控设备</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listMonitorData } from '@/api/monitorList'
|
||||
import { getStoreId } from '@/utils/auth'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 真实的设备列表数据
|
||||
deviceList: [],
|
||||
pageType: '1' ,// 1 为实时监控,0 为历史回放
|
||||
storeId:''
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.storeId = getStoreId();
|
||||
if (!this.storeId) {
|
||||
uni.showToast({
|
||||
title: '未获取到门店信息,请重新登录',
|
||||
icon: 'none'
|
||||
});
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 1500);
|
||||
return;
|
||||
}
|
||||
if (options && options.type !== undefined) {
|
||||
this.pageType = options.type;
|
||||
}
|
||||
|
||||
// 动态修改导航栏标题
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.pageType === '0' ? '选择回放设备' : '监控设备列表'
|
||||
});
|
||||
|
||||
// 发起接口请求,获取真实的设备列表
|
||||
this.fetchDeviceList();
|
||||
},
|
||||
methods: {
|
||||
async fetchDeviceList() {
|
||||
uni.showLoading({ title: '加载中...' });
|
||||
try {
|
||||
const res = await listMonitorData(this.storeId);
|
||||
if (res.code === 200 && res.data) {
|
||||
// 过滤掉 deviceType 不是 1 的设备,并映射字段以便列表渲染
|
||||
this.deviceList = res.data
|
||||
.filter(item => item.deviceType === '1' || item.deviceType === 1)
|
||||
.map(item => {
|
||||
return {
|
||||
name: item.deviceName,
|
||||
uid: item.deviceCode,
|
||||
isNvr: item.deviceModel == '1'?false:true, // 1单机(IPC) false 2主机(NVR) true
|
||||
channel: item.channel !== undefined ? item.channel : 4, // 这里先当成总通道数,默认给个 4
|
||||
// online: item.status === '1' || item.status === 1 || item.online // 假设 1 代表在线
|
||||
};
|
||||
});
|
||||
} else {
|
||||
uni.showToast({ title: '获取数据失败', icon: 'none' });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取监控列表失败', error);
|
||||
uni.showToast({ title: '网络请求异常', icon: 'none' });
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
}
|
||||
},
|
||||
goToMonitorDetail(device) {
|
||||
// 如果需要判断在线状态,可在这里解开注释
|
||||
// if (!device.online) {
|
||||
// uni.showToast({ title: '设备离线,无法查看', icon: 'none' });
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (this.pageType === '0') {
|
||||
// 跳转到历史回放页面,携带 uid、isNvr 和 channel
|
||||
uni.navigateTo({
|
||||
url: `/package_a/playback/playback?uid=${device.uid}&isNvr=${device.isNvr}&channel=${device.channel}`
|
||||
});
|
||||
} else {
|
||||
// 默认跳转到实时监控页面,携带 uid、isNvr 和 channel
|
||||
uni.navigateTo({
|
||||
url: `/package_a/monitor/monitor?uid=${device.uid}&isNvr=${device.isNvr}&channel=${device.channel}`
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 30rpx 40rpx;
|
||||
background-color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.list-container {
|
||||
flex: 1;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.device-card {
|
||||
background-color: #ffffff;
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.device-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.device-name {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.device-uid {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.device-status {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.status-dot {
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
border-radius: 6rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.status-dot.online {
|
||||
background-color: #52c41a;
|
||||
}
|
||||
|
||||
.status-dot.offline {
|
||||
background-color: #999999;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.device-action {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.action-text {
|
||||
font-size: 26rpx;
|
||||
color: #007aff;
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
|
||||
.empty-tips {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding-top: 100rpx;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -33,10 +33,26 @@
|
|||
<view class="setting-row">
|
||||
<text class="setting-label">设备类型:</text>
|
||||
<view class="options-group">
|
||||
<text class="option-btn" :class="!isNvr ? 'active-btn' : ''" @click="changeNvr(false)">单体(IPC)</text>
|
||||
<text class="option-btn" :class="isNvr ? 'active-btn' : ''" @click="changeNvr(true)">主机(NVR)</text>
|
||||
<text class="option-btn" v-if="!isNvr" :class="!isNvr ? 'active-btn' : ''" @click="changeNvr(false)">单体(IPC)</text>
|
||||
<text class="option-btn" v-else :class="isNvr ? 'active-btn' : ''" @click="changeNvr(true)">主机(NVR)</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="setting-row" v-if="isNvr && totalChannel > 0">
|
||||
<text class="setting-label">通道:</text>
|
||||
<!-- nvue 的 flex 默认不支持换行(flex-wrap),通道多的话外面套一个 scroll-view 可以左右滑动 -->
|
||||
<scroll-view class="channel-scroll" scroll-x="true" show-scrollbar="false">
|
||||
<view class="options-group channel-group">
|
||||
<text
|
||||
class="option-btn"
|
||||
v-for="(item, index) in totalChannel"
|
||||
:key="index"
|
||||
:class="currentChannel === index ? 'active-btn' : ''"
|
||||
@click="changeChannel(index)">
|
||||
CH{{ index + 1 }}
|
||||
</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 日期选择 -->
|
||||
<view class="setting-row date-control-row">
|
||||
|
|
@ -62,27 +78,34 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
deviceUid: 'HLTY036190SYNSK',
|
||||
deviceUid: '',
|
||||
currentChannel: 0,
|
||||
isNvr: true,
|
||||
playDate: '',
|
||||
playTime: '',
|
||||
statusMsg: '等待操作',
|
||||
isPlaying: false
|
||||
isPlaying: false,
|
||||
totalChannel:1
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
if (options && options.uid) {
|
||||
this.deviceUid = 'HLTY036190SYNSK';
|
||||
this.deviceUid = options.uid;
|
||||
}
|
||||
if (options && typeof options.isNvr !== 'undefined') {
|
||||
this.isNvr = options.isNvr === 'true';
|
||||
this.isNvr = options.isNvr;
|
||||
}
|
||||
// 接收总通道数
|
||||
if (options && options.channel) {
|
||||
this.currentChannel = parseInt(options.channel);
|
||||
this.totalChannel = parseInt(options.channel);
|
||||
// 如果通道数不合理(比如0或者NaN),给个默认值
|
||||
if (!this.totalChannel || this.totalChannel <= 0) {
|
||||
this.totalChannel = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化默认时间为当前时间
|
||||
|
|
@ -113,6 +136,18 @@
|
|||
setTimeout(() => { this.startPlayback(); }, 1000);
|
||||
}
|
||||
},
|
||||
changeChannel(ch) {
|
||||
console.log(ch);
|
||||
if (this.currentChannel === ch) return;
|
||||
this.currentChannel = ch;
|
||||
// 如果正在播放,切换通道后重新播放
|
||||
if (this.isPlaying) {
|
||||
this.stopPlayback();
|
||||
setTimeout(() => {
|
||||
this.startPlayback();
|
||||
}, 500);
|
||||
}
|
||||
},
|
||||
prevDay() {
|
||||
// 解决部分环境解析 YYYY-MM-DD 报错,替换为 YYYY/MM/DD
|
||||
let d = new Date(this.playDate.replace(/-/g, '/'));
|
||||
|
|
@ -227,6 +262,40 @@
|
|||
|
||||
<style>
|
||||
/* nvue 样式 */
|
||||
.setting-row {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
.setting-label {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
width: 120rpx;
|
||||
}
|
||||
.options-group {
|
||||
flex-direction: row;
|
||||
flex: 1;
|
||||
}
|
||||
.channel-scroll {
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
}
|
||||
.channel-group {
|
||||
flex-direction: row;
|
||||
padding-bottom: 10rpx; /* 预留一点底部空间,防止被遮挡 */
|
||||
}
|
||||
.option-btn {
|
||||
padding: 10rpx 20rpx;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 8rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
.active-btn {
|
||||
color: #ffffff;
|
||||
background-color: #007aff;
|
||||
}
|
||||
.playback-container {
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
|
|
|
|||
|
|
@ -74,6 +74,12 @@
|
|||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "monitorList/monitorList",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ export default {
|
|||
|
||||
// #ifndef MP
|
||||
uni.navigateTo({
|
||||
url: '/package_a/monitor/monitor'
|
||||
url: '/package_a/monitorList/monitorList?type=1' // type=1 表示查看实时监控
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
|
|
@ -386,7 +386,7 @@ export default {
|
|||
|
||||
// #ifndef MP
|
||||
uni.navigateTo({
|
||||
url: '/package_a/playback/playback'
|
||||
url: '/package_a/monitorList/monitorList?type=0' // type=0 表示查看回放
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue