1
shuishen
2022-11-18 a9a6d5240bbeba4436437543d942ee9e22093589
1
2 files modified
1 files added
419 ■■■■■ changed files
src/router/page/index.js 10 ●●●●● patch | view | raw | blame | history
src/views/lyout/index.vue 46 ●●●● patch | view | raw | blame | history
src/views/video/list.vue 363 ●●●●● patch | view | raw | blame | history
src/router/page/index.js
@@ -55,7 +55,15 @@
                meta: {
                    title: '视频监控'
                },
                component: video
                children: [
                    {
                        path: 'list',
                        meta: {
                            title: '列表查询'
                        },
                        component: video
                    },
                ]
            },
            {
                path: 'activity',
src/views/lyout/index.vue
@@ -2,7 +2,7 @@
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2022-08-18 16:18:24
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2022-11-14 14:13:45
 * @LastEditTime: 2022-11-18 09:56:13
 * @FilePath: \srs-police-affairs\src\views\lyout\index.vue
 * @Description: 
 * 
@@ -19,8 +19,16 @@
            <!-- 菜单导航 -->
            <div class="menu-list">
                <div class="nav-list" :class="{ on: currentUrl == item.path }" @click="goToPath(item)"
                    v-for="(item, index) in menuList" :key="index">{{ item.menuName }}</div>
                <div @mouseenter="item.childrenFlag = true" @mouseleave="item.childrenFlag = false" class="nav-list"
                    :class="{ on: currentUrl.indexOf(item.path) != -1 }" @click="goToPath(item)"
                    v-for="(item, index) in menuList" :key="index">
                    {{ item.menuName }}
                    <div class="sub-nav-list" v-show="item.children && item.childrenFlag">
                        <div v-for="(subItem, subIndex) in item.children" :key="subIndex" @click="goToPath(subItem)">
                            {{ subItem.menuName }}
                        </div>
                    </div>
                </div>
            </div>
            <!-- 用户登录展示的 -->
@@ -65,8 +73,18 @@
                },
                {
                    menuName: '视频监控',
                    path: '/lyout/video'
                    path: '/lyout/video',
                    childrenFlag: false,
                    children: [
                        {
                            menuName: '视频监控',
                            path: '/lyout/video/list'
                        },
                        {
                            menuName: '视频监控',
                            path: '/lyout/video/region'
                        }
                    ]
                },
                {
                    menuName: '安保活动',
@@ -121,6 +139,8 @@
         * @return {*} 没有返回值
         */
        goToPath (params) {
            if (params.children && params.children.length > 0) return
            if (params.path) {
                if (this.$route.path == params.path) return
                this.$router.push(params.path)
@@ -229,6 +249,7 @@
            }
            .nav-list {
                position: relative;
                padding: 0 16px;
                display: flex;
                align-items: center;
@@ -238,6 +259,21 @@
                font-weight: 400;
                cursor: pointer;
                border-bottom: 3px solid transparent;
                .sub-nav-list {
                    padding: 10px 0;
                    position: absolute;
                    top: 72px;
                    width: 100%;
                    background: $bg-blue;
                    div {
                        height: 36px;
                        text-align: center;
                        line-height: 36px;
                        font-size: 18px;
                    }
                }
            }
        }
src/views/video/list.vue
New file
@@ -0,0 +1,363 @@
<!--
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2022-08-18 16:18:17
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2022-11-18 09:26:32
 * @FilePath: \srs-police-affairs\src\views\video\index.vue
 * @Description: 辖区管理
 *
 * Copyright (c) 2022 by shuishen 1109946754@qq.com, All Rights Reserved.
-->
<template>
    <div class="container">
        <div v-show="boxShow" class="container-content">
            <div class="search-box">
                <input v-model="searchValue" @input="searchChange" type="text" placeholder="请输入搜索条件" />
                <button @click="searchClick" class="el-icon-search"></button>
            </div>
            <div class="draw-btn">
                <el-button type="primary" size="mini" @click="draw('polygon')">绘制面</el-button>
                <el-button type="primary" size="mini" @click="draw('polyline')">绘制线</el-button>
                <el-button type="primary" size="mini" @click="removeDrawLayer">清除</el-button>
            </div>
            <div v-show="true" class="search-val-box">
                <div @click="searchVlaClick(item)" v-for="(item, index) in searchArray" :key="index">{{ item.name }}
                </div>
            </div>
            <div class="list-show">
                <div class="car-list">
                    <div class="list-box">
                        <el-table :data="monitoringList.slice((currentPage - 1) * pagesize, currentPage * pagesize)"
                            style="width: 100%"
                            :header-cell-style="{ 'text-align': 'center', 'background-color': '#203c60', 'borderColor': '#324e75' }"
                            :cell-style="{ 'text-align': 'center', 'borderColor': '#324e75' }" @cell-click="rowClick">
                            <el-table-column prop="name" label="设备名称" min-width="50%"></el-table-column>
                            <el-table-column prop="manufacturer" label="设备类型" min-width="50%"></el-table-column>
                        </el-table>
                    </div>
                    <div class="pages">
                        <el-pagination background layout="prev, pager, next" :total="monitoringList.length"
                            :page-size="pagesize" pager-count="3" :current-page="currentPage"
                            @current-change="handleCurrentChange"></el-pagination>
                    </div>
                </div>
            </div>
        </div>
        <el-dialog :title="dialogTitle" :modal="true" :visible.sync="dialogVisible" :before-close="dialogBeforeClose"
            :close-on-click-modal="true" class="car-video-box">
            <video id="videoElement" autoplay controls width="100%" height="100%" style="object-fit: fill"></video>
        </el-dialog>
    </div>
</template>
<script>
import EntityDraw from "@/utils/EntityDraw.js"
import { listQuery, accurateSearch } from "@/utils/search.js"
import monitoringList from '@/assets/data/monitoring.js'
import { getVideoList, getDevices } from '@/api/video/index.js'
import flvjs from 'flv.js'
let graphicLayer = null
export default {
    data () {
        return {
            currentPage: 1,
            pagesize: 13,
            monitoringList: [],
            dialogTitle: '',
            dialogVisible: false,
            searchValue: '',
            searchArray: [],
            searchValBoxShow: false,
            boxShow: true,
            flvPlayer: null,
        }
    },
    created () {
        this.getVideoList()
    },
    mounted () {
        this.$parent.resize('400px', true)
        graphicLayer = new EntityDraw()
    },
    methods: {
        handleCurrentChange: function (currentPage) {
            this.currentPage = currentPage
        },
        getVideoList () {
            getVideoList(1, 10).then(res => {
                this.monitoringList = res.data.data.list
                this.initMonitoringIcon()
            })
        },
        async getDevices (id) {
            let flvAddress = ''
            await getDevices(id).then(res => {
                if ('data' in res.data) {
                    flvAddress = res.data.data.flv
                } else {
                    flvAddress = 'nodata'
                }
            })
            return flvAddress
        },
        initMonitoringIcon () {
            this.monitoringList.forEach((item, index) => {
                this.$EventBus.$emit('layerPointAdd', {
                    layerName: 'monitoringLayers',
                    type: "billboard",
                    params: {
                        name: item.name,
                        lng: item.longitude,
                        lat: item.latitude,
                        alt: 100,
                        url: '/img/icon/video.png',
                        deviceId: item.deviceId
                    },
                    incident: this.siteClick
                })
            })
        },
        rowClick (row) {
            this.$EventBus.$emit('toPosition', {
                layerName: 'monitoringLayers',
                siteJd: row.longitude,
                siteWd: row.latitude,
                siteGd: 60000,
                siteHeading: -3,
                sitePitch: -90
            })
        },
        async siteClick (e) {
            if (this.flvPlayer != null) {
                this.flvPlayer.pause()
                this.flvPlayer.unload()
                this.flvPlayer.detachMediaElement()
                this.flvPlayer.destroy()
                this.flvPlayer = null
            }
            this.dialogTitle = e.overlay.attrParams.name
            this.dialogVisible = true
            let flvUrl = ''
            await this.getDevices(e.overlay.attrParams.deviceId).then(res => {
                flvUrl = res
            })
            if (flvjs.isSupported() && flvUrl != 'nodata') {
                var videoElement = document.getElementById('videoElement')
                this.flvPlayer = flvjs.createPlayer({
                    type: 'flv',
                    isLive: true,
                    hasAudio: false,
                    url: flvUrl
                })
                this.flvPlayer.attachMediaElement(videoElement)
                this.flvPlayer.load()
                this.flvPlayer.play()
            }
        },
        dialogBeforeClose () {
            // this.$refs.videoElement.pause()
            this.dialogVisible = false
        },
        searchChange () {
            if (this.searchValue == '') {
                this.searchValBoxShow = false
                this.searchArray = []
                this.monitoringList = monitoringList
            } else {
                this.searchArray = listQuery(monitoringList, this.searchValue, 'name')
                this.searchValBoxShow = true
            }
        },
        searchClick () {
            this.searchValBoxShow = false
            this.monitoringList = accurateSearch(monitoringList, this.searchValue, 'name')
        },
        searchVlaClick (item) {
            this.searchValBoxShow = false
            this.searchArray = []
            this.monitoringList = [item]
        },
        draw (type) {
            const that = this
            graphicLayer.activate(type, (lastEventData) => {
                console.log('数据更新', JSON.stringify(lastEventData))
            })
        },
        removeDrawLayer () {
            graphicLayer.clearLayer()
        },
        // 修改范围
        setRegion () {
            graphicLayer.addPolyLineGon(5000, (lastEventData) => {
                console.log('数据更新', JSON.stringify(lastEventData))
            })
        },
        // 大小重置
        boxResize (val) {
            this.boxShow = val
        },
    },
    destroyed () {
        this.$EventBus.$emit('mapRemoveLayer', {
            layerName: 'monitoringLayers',
            type: 'VectorLayer'
        })
        graphicLayer.destroy()
        this.$parent.resize('0px')
        if (this.flvPlayer != null) {
            this.flvPlayer.pause()
            this.flvPlayer.unload()
            this.flvPlayer.detachMediaElement()
            this.flvPlayer.destroy()
            this.flvPlayer = null
        }
    }
}
</script>
<style scoped lang="scss">
.container {
    position: relative;
    width: 400px;
    height: 100%;
    &-content {
        display: flex;
        flex-direction: column;
        width: 100%;
        height: 100%;
        color: #fff;
        background: $bg-color;
        .search-box {
            padding: 8px;
            height: 48px;
            display: flex;
            input {
                flex: 1;
                height: 100%;
                font-size: 16px;
                text-indent: 1em;
                color: #ffffff;
                background-color: transparent;
                border: 1px solid rgb(0, 92, 169);
                border-radius: 20px 0 0 20px;
            }
            input:focus {
                outline: none;
            }
            input::-webkit-input-placeholder {
                color: rgba(238, 238, 238, 0.7);
            }
            button {
                font-size: 24px;
                font-weight: 700;
                width: 80px;
                height: 100%;
                background-color: rgb(0, 92, 169);
                color: #fff;
                border: 1px solid rgb(0, 92, 169);
                cursor: pointer;
                border-radius: 0 20px 20px 0;
            }
            button:active {
                background-color: rgb(0, 92, 169);
                border: 1px solid rgb(0, 92, 169);
            }
        }
        .search-val-box {
            display: flex;
            flex-direction: column;
            position: absolute;
            top: 48px;
            left: 6px;
            width: calc(100% - 12px);
            max-height: 160px;
            text-align: left;
            color: #fff;
            background: rgba(16, 29, 74, 0.9);
            z-index: 1111;
            border-radius: 10px;
            overflow-y: auto;
            &>div {
                height: 100%;
                padding: 0 10px;
                line-height: 36px;
                cursor: pointer;
            }
        }
        .draw-btn {
            margin: 8px;
            margin-top: 0;
            display: flex;
            align-items: center;
            justify-content: space-around;
            height: 26px;
            .el-button {
                flex: 1;
            }
        }
        .list-show {
            flex: 1;
            &>div {
                height: 100%;
                display: flex;
                flex-direction: column;
                // background-color: #fff;
                .list-box {
                    flex: 1;
                }
            }
            .pages {
                height: 40px;
                display: flex;
                align-items: center;
                justify-content: center;
            }
        }
    }
}
</style>