guanqb
2022-11-18 35b56ac72c251d99e162e2d69decea99aba60995
增加空间查询页面
2 files modified
1 files added
547 ■■■■ changed files
src/router/page/index.js 8 ●●●●● patch | view | raw | blame | history
src/views/video/list.vue 92 ●●●●● patch | view | raw | blame | history
src/views/video/region.vue 447 ●●●●● patch | view | raw | blame | history
src/router/page/index.js
@@ -15,6 +15,7 @@
const police = () => import('../../views/police/index.vue')
const video = () => import('../../views/video/index.vue')
const videoList = () => import('../../views/video/list.vue')
const videoRegion = () => import('../../views/video/region.vue')
const activity = () => import('../../views/activity/index.vue')
const routes = [
@@ -65,6 +66,13 @@
                        },
                        component: videoList
                    },
                    {
                        path: 'region',
                        meta: {
                            title: '空间查询'
                        },
                        component: videoRegion
                    },
                ]
            },
            {
src/views/video/list.vue
@@ -22,23 +22,6 @@
                <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>
                <el-button
                    type="primary"
                    size="mini"
                    @click="inputpopup = true"
                    v-show="changeBtn"
                >修改范围</el-button>
            </div>
            <div class="range-input" v-show="changeBtn && inputpopup">
                <h3>请输入距离</h3>
                <input type="text" v-model="range" />
                <button @click="changeRange" class="btn">确定</button>
            </div>
            <div v-show="true" class="search-val-box">
                <div
                    @click="searchVlaClick(item)"
@@ -118,9 +101,6 @@
            searchValBoxShow: false,
            boxShow: true,
            flvPlayer: null,
            range: 5000,
            inputpopup: false,
            changeBtn: false,
        }
    },
@@ -243,40 +223,9 @@
            this.monitoringList = [item]
        },
        draw (type) {
            if (type == 'polyline') {
                this.inputpopup = false
                this.changeBtn = true
            } else {
                this.changeBtn = false
            }
            const that = this
            graphicLayer.activate(type, (lastEventData) => {
                console.log('数据更新', JSON.stringify(lastEventData))
            })
        },
        removeDrawLayer () {
            this.changeBtn = false
            graphicLayer.clearLayer()
        },
        // 修改范围
        setRegion (range) {
            graphicLayer.addPolyLineGon(range, (lastEventData) => {
                console.log('数据更新', JSON.stringify(lastEventData))
            })
        },
        // 大小重置
        boxResize (val) {
            this.boxShow = val
        },
        changeRange () {
            this.setRegion(this.range)
            this.inputpopup = false
        }
    },
@@ -377,47 +326,6 @@
                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;
            }
        }
        .range-input {
            position: absolute;
            right: -190px;
            top: 20px;
            width: 180px;
            height: 100px;
            background-color: $bg-color;
            input {
                outline: none;
                border: 1px solid #005ca9;
                background-color: transparent;
                width: 160px;
                height: 30px;
                margin-top: 10px;
                color: #fff;
                padding-left: 6px;
            }
            .btn {
                width: 60px;
                height: 30px;
                background-color: #65b1ff;
                color: #fff;
                border-radius: 4px;
                cursor: pointer;
                margin-top: 10px;
            }
        }
src/views/video/region.vue
New file
@@ -0,0 +1,447 @@
<!--
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2022-08-18 16:18:17
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2022-11-18 10:02:31
 * @FilePath: \srs-police-affairs\src\views\video\list.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>
                <el-button
                    type="primary"
                    size="mini"
                    @click="inputpopup = true"
                    v-show="changeBtn"
                >修改范围</el-button>
            </div>
            <div class="range-input" v-show="changeBtn && inputpopup">
                <h3>请输入距离</h3>
                <input type="text" v-model="range" />
                <button @click="changeRange" class="btn">确定</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,
            range: 5000,
            inputpopup: false,
            changeBtn: false,
        }
    },
    created () {
        this.getVideoList()
    },
    mounted () {
        this.$parent.$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) {
            if (type == 'polyline') {
                this.inputpopup = false
                this.changeBtn = true
            } else {
                this.changeBtn = false
            }
            const that = this
            graphicLayer.activate(type, (lastEventData) => {
                console.log('数据更新', JSON.stringify(lastEventData))
            })
        },
        removeDrawLayer () {
            this.changeBtn = false
            graphicLayer.clearLayer()
        },
        // 修改范围
        setRegion (range) {
            graphicLayer.addPolyLineGon(range, (lastEventData) => {
                console.log('数据更新', JSON.stringify(lastEventData))
            })
        },
        // 大小重置
        boxResize (val) {
            this.boxShow = val
        },
        changeRange () {
            this.setRegion(this.range)
            this.inputpopup = false
        }
    },
    destroyed () {
        this.$EventBus.$emit('mapRemoveLayer', {
            layerName: 'monitoringLayers',
            type: 'VectorLayer'
        })
        graphicLayer.destroy()
        this.$parent.$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;
            }
        }
        .range-input {
            position: absolute;
            right: -190px;
            top: 20px;
            width: 180px;
            height: 100px;
            background-color: $bg-color;
            input {
                outline: none;
                border: 1px solid #005ca9;
                background-color: transparent;
                width: 160px;
                height: 30px;
                margin-top: 10px;
                color: #fff;
                padding-left: 6px;
            }
            .btn {
                width: 60px;
                height: 30px;
                background-color: #65b1ff;
                color: #fff;
                border-radius: 4px;
                cursor: pointer;
                margin-top: 10px;
            }
        }
        .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>