lcny-admin-mobile-vue/src/pages/index/monitor.vue

655 lines
19 KiB
Vue

<template>
<view class="monitor-page bg-page">
<view class="utab-section">
<u-subsection
:list="list"
:current="current"
@change="sectionChange"
></u-subsection>
</view>
<view class="secreen-section" style="background-color: #fff">
<u-dropdown class="dropdown-box" v-if="current == 0" ref="uDropdown">
<u-dropdown-item
v-model="addressValue"
title="基地"
height="700rpx"
:options="deviceAddressList"
@change="change"
></u-dropdown-item>
<u-dropdown-item
v-model="device_id"
title="检测点"
height="700rpx"
:options="options2"
@change="change2"
></u-dropdown-item>
<u-dropdown-item
v-model="is_recommend"
title="全部"
:options="options3"
@change="change3"
></u-dropdown-item>
</u-dropdown>
<u-dropdown
class="dropdown-box"
v-if="current == 1"
ref="uDropdown2"
@open="openDropDown"
>
<u-dropdown-item
v-model="addressValue2"
title="基地"
height="700rpx"
:options="deviceAddressList2"
@change="change"
></u-dropdown-item>
<u-dropdown-item
v-model="device_id2"
title="检测点"
height="700rpx"
:options="options4"
@change="change4"
></u-dropdown-item>
<u-dropdown-item v-if="current == 1" title="日期">
<view class="slot-content" style="background-color: #ffffff">
<view class="select-date u-border-bottom" style="margin-bottom: 0">
<view class="name" @click="pickerTimeFn('start')">
<u-icon name="calendar" color="#333" size="32"></u-icon>
<text style="margin-left: 6rpx">开始时间:</text>
</view>
<view class="time_box">
<view
class="tip_txt"
v-if="!start_date_c"
@click="pickerTimeFn('start')"
>请选择开始时间</view
>
<view class="tile_val" v-else @click="pickerTimeFn('start')">{{
start_date_c
}}</view>
<view
class="delete_btn"
v-if="start_date_c"
@click="deleteDateFn('start')"
>
<u-icon name="close-circle" color="#333" size="34"></u-icon>
</view>
</view>
</view>
<view class="select-date u-border-bottom" style="margin-bottom: 0">
<view class="name" @click="pickerTimeFn('end')">
<u-icon name="calendar" color="#333" size="32"></u-icon>
<text style="margin-left: 6rpx">结束时间:</text>
</view>
<view class="time_box">
<view
class="tip_txt"
v-if="!end_date_c"
@click="pickerTimeFn('end')"
>请选择结束时间</view
>
<view class="tile_val" v-else @click="pickerTimeFn('end')">{{
end_date_c
}}</view>
<view
class="delete_btn"
v-if="end_date_c"
@click="deleteDateFn('end')"
>
<u-icon name="close-circle" color="#333" size="34"></u-icon>
</view>
</view>
</view>
<view class="select-date u-border-bottom" v-if="selectedTimeTip">
<view class="tip_err_text">
请选择开始时间和结束时间,查询视频
</view>
</view>
<view class="btn_group">
<u-button class="btn" @click="resetSecreen()">重置</u-button>
<u-button
class="btn"
type="primary"
@click="selectedDateConform()"
>查询</u-button
>
</view>
</view>
</u-dropdown-item>
</u-dropdown>
</view>
<view class="secreen-show-box mt20" v-if="current == 0 && addressName">
<view class="label_t">当前位置:</view>
<view class="info"
>{{ addressName }}-{{ device_id ? device_id : '全部' }}-{{
is_recommend ? '推荐' : '全部'
}}</view
>
</view>
<view class="secreen-show-box mt20" v-if="current == 1 && q_start_time">
<view class="label_t">查询:</view>
<view class="info">
<view>{{ addressName2 }}-{{ device_id2 }}</view>
<view>{{ q_start_time }} 到 {{ q_end_time }}</view>
</view>
</view>
<view class="content-box">
<view class="video_ul" v-show="current == 0">
<view class="video_li" v-for="(video, index) in videoList" :key="index">
<view class="video_cd">
<!-- #ifdef H5 -->
<videoM3u8H5 v-if="video.video_type=='m3u8'" :url="video.video_url" :id="`m_${index}_refsM3u8`"></videoM3u8H5>
<video-flv-h5 v-else :url="video.video_url"></video-flv-h5>
<!-- #endif -->
</view>
<view class="bottom-box">
<view class="row flex-row">
<view class="lab">推荐:</view>
<u-switch
v-model="video.bl_recommend"
size="30"
@change="changeRecommend($event, index)"
></u-switch>
</view>
<view class="address"
>{{ video.base_name }}-{{ video.monitoring_point }}</view
>
</view>
</view>
<u-loadmore :status="loading" />
</view>
<view class="video_ul" v-show="current == 1">
<view
class="video_li"
v-for="(video, index) in videoList2"
:key="index"
>
<view class="video_cd">
<!-- #ifdef H5 -->
<videoM3u8H5 v-if="video.video_type=='m3u8'" :url="video.video_url" :id="`m_${index}_refsM3u82`" ></videoM3u8H5>
<video-flv-h5 v-else :url="video.video_url"></video-flv-h5>
<!-- #endif -->
</view>
<view class="bottom-box">
<view class="address"
>{{ video.base_name }}-{{ video.monitoring_point }}</view
>
</view>
</view>
<u-loadmore :status="loading2" v-if="loading2" />
<u-empty
text="请选择要查看的视频的日期"
mode="history"
margin-top="100"
v-if="!(videoList2 && videoList2.length)"
></u-empty>
</view>
</view>
<!-- 选择时间 -->
<u-picker
mode="time"
v-model="pickerShow"
@confirm="pickerChange"
:params="pickerParams"
:default-time="defaultTime"
></u-picker>
</view>
</template>
<script>
import videoFlvH5 from '@/components/video-flv-h5/video-flv-h5.vue'
import videoM3u8H5 from '@/components/video-m3u8-h5/video-m3u8-h5.vue'
import Request from '@/api/luch-request/index.js'
const http = new Request()
export default {
components: { videoFlvH5,videoM3u8H5 },
data() {
return {
list: [
{
name: '监控',
},
{
name: '视频',
},
],
current: 0,
//筛选
q_start_time: '',
q_end_time: '',
deviceAddressList: [], //筛选设备地区列表
addressName: '',
addressValue: '',
device_id: '', //检测点 - options2中的设备id
options2: [],
start_date_c: '',
end_date_c: '',
device_type: 1, //监控
is_recommend: 0,
options3: [
{
label: '全部',
value: 0,
},
{
label: '推荐',
value: 1,
},
],
per_page: 4,
page: 1,
pickerParams: {
year: true,
month: true,
day: true,
hour: true,
minute: true,
second: false,
},
defaultTime: '',
pickerShow: false, //选择
ctimeType: '', //当前点击
addressValue2: '',
addressName2: '',
device_id2: '',
options4: [],
websocket: {},
videoList: [],
videoList2: [],
per_page2: 4,
page2: 1,
loading: 'loading',
loading2: '',
selectedTimeTip: false, //选择时间段提示
}
},
onLoad() {
this.queryWebsocketIp()
},
methods: {
sectionChange(index) {
this.current = index
},
//地区1
change(val) {
console.log(val)
let narray = this.deviceAddressList.filter((item) => {
return item.value == val
})
console.log(narray)
if (this.current == 0) {
this.addressName = narray[0].name
} else {
this.addressName2 = narray[0].name
}
if (val == '') {
this.addressName = '全部'
this.queryDevices()
} else {
this.queryAddressDevicePoints(val)
}
},
//地区下设备id
change2(val) {
console.log(val)
this.queryDevices()
},
//推荐
change3(val) {
this.queryDevices()
},
//视频下-设备
change4(val) {},
//时间选择
pickerTimeFn(type) {
this.ctimeType = type
this.pickerShow = true
},
//日期范围
pickerChange(e) {
console.log(e, '日期范围')
let dateTime = `${e.year}-${e.month}-${e.day} ${e.hour}:${e.minute}`
if (this.ctimeType == 'start') {
this.start_date_c = dateTime
} else if (this.ctimeType == 'end') {
this.end_date_c = dateTime
} else {
}
console.log(dateTime, '日期范围')
},
//删除选择的时间
deleteDateFn(type) {
if (type == 'start') {
this.start_date_c = ''
} else if (type == 'end') {
this.end_date_c = ''
} else {
}
},
resetSecreen() {
this.start_date_c = ''
this.end_date_c = ''
},
selectedDateConform() {
if (this.start_date_c && this.end_date_c) {
this.selectedTimeTip = false
this.q_start_time = this.start_date_c
this.q_end_time = this.end_date_c
this.queryDevices2()
this.$refs.uDropdown2.close()
} else {
this.selectedTimeTip = true
}
},
//时间筛选
openDropDown(index) {
console.log(index, 'openDropDown')
this.selectedTimeTip = false
if (index == 2) {
//日期
this.start_date_c = this.q_start_time
this.end_date_c = this.q_end_time
}
},
//推特
changeRecommend(value, index) {
console.log(value, index)
let id = this.videoList[index].id
this.recommendId(id)
},
recommendId(id) {
this.$http
.put(`/api/devices-update-recommend/${id}`)
.then(({ data }) => {
console.log(data, 'recommendId===')
})
.catch((err) => {})
},
async queryWebsocketIp() {
let params = {
_t: new Date().getTime(),
}
const { data } = await this.$http.get('/api/ffmpeg-websocket-ip', {
params: params,
})
try {
console.log(data, 'queryWebsocketIp')
if (data.code == 200) {
this.websocket = data.data
}
} catch (e) {
//TODO handle the exception
}
this.queryDeviceBasics('init')
},
//查询监测
queryDevices(type) {
if (type != 'more') {
this.loading = 'loadmore'
this.page = 1
}
let params = {
type: this.device_type,
status: 1, //在线
per_page: this.per_page,
page: this.page++,
_t: new Date().getTime(),
}
if (this.addressValue) {
params['base'] = this.addressValue
}
if (this.device_id) {
params['point'] = this.device_id
}
if (this.is_recommend) {
params['is_recommend'] = this.is_recommend
}
this.loading = 'loading'
this.$http
.get('/api/devices', { params: params })
.then(async ({ data }) => {
this.loading = 'loadmore'
if (type != 'more') {
this.videoList = []
}
console.log(data, '监测视频')
if (data.code == 200) {
let list = data.data
for (let item of list) {
let url = item.extends.rtsp_url
let { ip, port } = this.websocket
if (url) {
item.video_url = `ws://${ip}:${port}/rtsp?url=${window.btoa(
url
)}`
}
const { supplier, extends: extend, sn } = item
if (item.supplier.id == 'device-supplier-biang') {
const { data } = await http.get(
'https://yun.bigdata5s.com/api/open-api/open/getSeedingLive',
{
params: {
username: extend.username,
password: extend.password,
equipmentCode: sn,
channelNo: extend.passage,
},
}
)
item.video_url = data.data
item.video_type = 'm3u8'
}
item.bl_recommend = item.is_recommend == 1 ? true : false
}
this.videoList = this.videoList.concat(list)
if (data.meta.current_page >= data.meta.last_page) {
this.loading = 'nomore'
}
console.log(this.videoList, data)
}
})
.catch(() => {
this.loading = 'loadmore'
})
},
//查询视频
queryDevices2(type) {
if (type != 'more') {
this.loading2 = 'loadmore'
this.page2 = 1
}
let params = {
type: this.device_type,
status: 1, //在线
per_page: this.per_page2,
page: this.page2++,
_t: new Date().getTime(),
}
if (this.addressValue2) {
params['base'] = this.addressValue2
}
if (this.device_id) {
params['point'] = this.device_id2
}
if (this.q_start_time) {
//时间
params['start_time'] = this.q_start_time
params['end_time'] = this.q_end_time
}
this.loading2 = 'loading'
this.$http
.get('/api/devices', { params: params })
.then(({ data }) => {
this.loading2 = 'loadmore'
if (type != 'more') {
this.videoList2 = []
}
console.log(data, '监测视频')
if (data.code == 200) {
let list = data.data
for (let item of list) {
let url = item.extends.rtsp_url
if (url) {
let { username, password, ip, passage, port } = item.extends
let stime = this.$u.timeFormat(
params['start_time'],
'yyyy_mm_dd_hh_MM_ss'
)
let etime = this.$u.timeFormat(
params['end_time'],
'yyyy_mm_dd_hh_MM_ss'
)
let p_url = `rtsp://${username}:${password}@${ip}:${port}/cam/playback?channel=${passage}&subtype=0`
let rtsp_url = `${p_url}&starttime=${stime}&endtime=${etime}`
item.video_url = `ws://${this.websocket.ip}:${
this.websocket.port
}/rtsp?url=${window.btoa(rtsp_url)}}`
console.log(rtsp_url, item.video_url, '视频url')
}
}
this.videoList2 = this.videoList2.concat(list)
if (data.meta.current_page >= data.meta.last_page) {
this.loading2 = 'nomore'
}
}
})
.catch(() => {
this.loading2 = 'loadmore'
})
},
//查询地址筛选
queryDeviceBasics(type) {
let params = {
device_type: this.device_type,
_t: new Date().getTime(),
}
this.$http
.get('/api/agricultural-device-basic', { params: params })
.then(({ data }) => {
console.log(data)
if (data.code == 200) {
let _data = data.data
if(_data.length==0){
this.loading = 'nomore'
return this.$u.toast('没有关联基地')
}
for (let item of _data) {
item['label'] = item.name
item['value'] = item.id
}
this.deviceAddressList = JSON.parse(JSON.stringify(_data))
this.deviceAddressList2 = _data
this.addressValue = _data[0].id
this.addressName = _data[0].name
this.addressValue2 = _data[0].id
this.addressName2 = _data[0].name
this.deviceAddressList.unshift({ label: '全部', value: '' })
this.queryAddressDevicePoints(_data[0].id, type)
}
})
.catch(() => {})
},
//查询地址下的设备监控点
queryAddressDevicePoints(id, type) {
let params = {
device_type: this.device_type,
agricultural_basic: id,
_t: new Date().getTime(),
}
this.$http
.get(`/api/agricultural-device-point/${id}`, { params: params })
.then(({ data }) => {
console.log(data)
if (data.code == 200) {
let _data = data.data
let options = []
for (let k in _data) {
let item = {}
item['label'] = _data[k]
item['value'] = _data[k]
options.push(item)
}
console.log(type, '初始查询')
console.log(this.options2, this.device_id, 'this.options2')
if (this.current == 0) {
//监控
this.options2 = JSON.parse(JSON.stringify(options))
this.device_id = options[0].value
this.options2.unshift({ label: '全部', value: '' })
this.queryDevices()
} else {
//视频
this.options4 = options
this.device_id2 = options[0].value
}
if (type == 'init') {
//初始查询
this.options4 = options
this.device_id2 = options[0].value
}
}
})
.catch(() => {})
},
},
//触底加载
onReachBottom() {
if (this.current == 0) {
if (this.loading == 'loadmore') {
this.queryDevices('more')
}
} else {
if (this.loading2 == 'loadmore') {
this.queryDevices2('more')
}
}
},
}
</script>
<style lang="scss" scoped>
.monitor-page {
background-color: #fafafa;
}
.utab-section {
padding: 30rpx;
}
.content-box {
padding: 30rpx;
}
.video_ul {
.video_li {
background-color: #fff;
width: 100%;
padding: 0 12rpx;
margin-bottom: 30rpx;
.video_cd {
width: 100%;
height: 400rpx;
padding-top: 20rpx;
}
.bottom-box {
padding-top: 30rpx;
padding-bottom: 30rpx;
padding-left: 20rpx;
padding-right: 20rpx;
.row {
display: flex;
align-items: center;
margin-bottom: 12rpx;
}
}
.address {
font-size: 28rpx;
}
}
}
</style>