shuishen
2023-04-01 e8efe7370ab9f2b9dfb07b0ae70b0e06d98e37c8
src/views/video/list.vue
@@ -2,7 +2,7 @@
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2022-08-18 16:18:17
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2023-03-31 17:07:47
 * @LastEditTime: 2023-04-01 17:09:18
 * @FilePath: \srs-police-affairs\src\views\video\list.vue
 * @Description: 辖区管理
 * 
@@ -13,8 +13,11 @@
    <div class="list container">
        <div v-show="boxShow" class="container-content">
            <div class="search-box">
                点位名称:
                <input v-model="searchValue" @input="searchChange" type="text" placeholder="请输入…" />
                <span style="display: inline-block; white-space:nowrap;">
                    点位名称:
                </span>
                <el-input size="small" placeholder="请输入…" v-model="searchValue" @change="searchChange" clearable>
                </el-input>
            </div>
            <div class="draw-btn">
@@ -41,7 +44,7 @@
                            &nbsp;
                            <span v-show="node.data.number && node.data.number != -1">
                            <span v-show="'number' in node.data && node.data.number != -1">
                                ({{
                                    node.data.number
                                }}个)
@@ -86,13 +89,11 @@
        <el-dialog :title="drawDialogTitle" :modal="false" :visible.sync="drawDialogVisible"
            :before-close="drawDialogBeforeClose" :close-on-click-modal="true" class="video-draw-box">
            <div>
                <div>名称:</div>
                <input type="text" v-model="drawName" placeholder="请输入绘制线的名称" />
            </div>
            <div v-show="inputpopup">
                <div>距离:</div>
                <input type="text" v-model="range" placeholder="请输入绘制线的范围" />
                <div>
                    <input type="text" v-model="range" placeholder="请输入缓冲范围" />
                </div>
            </div>
            <div class="line">
                <div class="value-name-box">颜色:</div>
@@ -102,8 +103,15 @@
                </div>
            </div>
            <div>
                <button @click="saveDrawInfo">保存</button>
                <button @click="cancelSaveDrawInfo">取消</button>
                <div class="value-name-box">设置透明度:</div>
                <div class="alpha">
                    <el-slider :min="1" v-model="choosePlotColorAlpha" :format-tooltip="formatTooltip"></el-slider>
                </div>
            </div>
            <div class="button">
                <button @click="searchDraw">查询</button>
                <button @click="drawDialogBeforeClose">取消</button>
            </div>
        </el-dialog>
    </div>
@@ -121,29 +129,30 @@
    equipmentNum = window.BASE_URL_CONFIG.VUE_APP_INTRANET_EQUIPMENT
}
import EntityDraw from "@/utils/EntityDraw.js"
import { getEquipmentAll } from '@/api/home/index.js'
import {
    getDevices,
    getRegionList,
    insertRegionSaveList,
    getTreeDevices,
    getSearchTreeDevices,
    getTreeDevicesNearby
} from '@/api/video/index.js'
import flvjs from 'flv.js'
let graphicLayer = null
import { initMapPosition } from '@/utils/mapPositionInit'
let plot = undefined
let drawPlotLayers = null
let loading = null
let drawFlag = false
let drawPlotData = null
export default {
    inject: ['userInfo'],
    data () {
        return {
            monitoringList: [],
            monitoringSaveList: [],
            dialogTitle: '',
            drawDialogTitle: '绘制线面',
            dialogVisible: false,
@@ -154,7 +163,6 @@
            range: 100,
            inputpopup: false,
            changeBtn: false,
            drawName: '',
            drawType: 1,
            props: {
                label: 'name',
@@ -168,7 +176,6 @@
            defaultExpandedKeys: [],
            searchLazyFlag: true,
            searchTreeData: [],
            drawPlotData: {},
            chooseRangeColor: '#FF0000',
            predefineColors: [
                '#ff4500',
@@ -187,11 +194,15 @@
                '#c7158577'
            ],
            videoPlayShow: false
            videoPlayShow: false,
            startDrawFlag: false,
            choosePlotColorAlpha: 50
        }
    },
    created () {
    },
    mounted () {
@@ -204,10 +215,17 @@
                    clampToModel: true
                })
            }
            this.getEquipmentAll({ type: 1, deptid: this.userInfo.dept_id })
        })
    },
    methods: {
        // 计算透明度值
        formatTooltip (val) {
            return val / 100
        },
        async getDevices (channelId) {
            let flvAddress = ''
            await getDevices(channelId).then(res => {
@@ -269,22 +287,35 @@
        },
        drawDialogBeforeClose () {
            this.drawName = ''
            plot.stop()
            if (drawPlotLayers != null) {
                drawPlotLayers.clear()
            }
            this.$EventBus.$emit('mapRemoveLayer', {
                layerName: 'monitoringLayers',
                type: 'VectorLayer'
            })
            this.drawDialogVisible = false
        },
        searchChange (e) {
            if (e.target.value.trim() != '') {
            this.inputpopup = false
            plot.stop()
            if (drawPlotLayers != null) {
                drawPlotLayers.clear()
            }
            drawPlotData = null
            if (e.trim() != '') {
                this.searchLazyFlag = false
                this.loading()
                this.$EventBus.$emit('mapClearLayer', {
                    layerName: 'treeValAllLayer',
                    type: 'VectorLayer'
                })
                this.searchTreeData = []
                getSearchTreeDevices({
                    deviceId: equipmentNum,
                    parentId: '361102',
@@ -292,20 +323,48 @@
                    name: this.searchValue.trim()
                }).then(res => {
                    this.searchTreeData = res.data.data
                    res.data.data.length && res.data.data.forEach(item => {
                        this.$EventBus.$emit('layerPointAdd', {
                            layerName: 'treeValAllLayer',
                            type: "billboard",
                            layerType: 'ClusterLayer',
                            params: {
                                ...item,
                                text: item.name,
                                lng: item.longitude,
                                lat: item.latitude,
                                url: item.status == 1 ? '/img/icon/video.png' : '/img/icon/video-off.png',
                                channelId: item.channelId,
                                status: item.status,
                                disableDepthTestDistance: Number.POSITIVE_INFINITY
                            },
                            incident: this.siteClick,
                            // mouseOverIncident: this.pointMouseOver,
                            // mouseOutIncident: this.pointMouseOut,
                        })
                    })
                    this.closeLoading()
                })
            } else {
                this.searchLazyFlag = true
                this.getEquipmentAll({ type: 1, deptid: this.userInfo.dept_id })
            }
        },
        // 封装方法绘制线面 type:polygon/polyline
        // draww (type) {
        //     if (graphicLayer == null) graphicLayer = new EntityDraw()
        //     graphicLayer.activate(type, (lastEventData) => {
        //     })
        // },
        draw (type) {
            const that = this
            drawFlag = false
            if (this.startDrawFlag == true) {
                drawFlag = true
                plot && plot.stop()
                drawFlag = false
                this.startDrawFlag = false
            }
            this.startDrawFlag = true
            if (type == 'polyline') {
                this.inputpopup = true
                this.drawType = 1
@@ -313,44 +372,34 @@
                this.inputpopup = false
                this.drawType = 2
            }
            plot && plot.draw(type, overlay => {
                if (drawFlag) return
                if (overlay) {
                    drawPlotData = overlay
                    drawPlotData.customType = type
                    that.range = 100
                    drawPlotLayers.addOverlay(overlay)
                    plot.edit(overlay)
                    if (overlay) {
                        drawPlotLayers.addOverlay(overlay)
                        plot.edit(overlay, (e) => {
                            this.drawDialogVisible = true
                            this.range = 100
                            this.drawPlotData = overlay
                            document.oncontextmenu = function () {
                                return false
                            }
                            this.getRegionList(type, overlay)
                        })
                    }
                    setTimeout(() => {
                        that.drawDialogVisible = true
                    }, 100)
                }
            }, { material: global.DC.Color.RED })
            }, { material: global.DC.Color.RED.withAlpha(0.5) })
        },
        removeDrawLayer () {
            this.inputpopup = false
            this.monitoringList = this.monitoringSaveList
            plot.stop()
            if (drawPlotLayers != null) {
                drawPlotLayers.clear()
            }
            this.drawPlotData = []
            this.$EventBus.$emit('mapRemoveLayer', {
                layerName: 'monitoringLayers',
                type: 'VectorLayer'
            })
        },
        // 修改范围
        setRegion (range) {
            graphicLayer.addPolyLineGon(range, (lastEventData) => {
                // this.getRegionList('polyline', JSON.stringify(lastEventData))
            })
            drawPlotData = null
            this.getEquipmentAll({ type: 1, deptid: this.userInfo.dept_id })
        },
        // 大小重置
@@ -358,147 +407,102 @@
            this.boxShow = val
        },
        changeRange () {
            this.setRegion(this.range)
        searchDraw () {
            this.searchLazyFlag = false
            this.searchValue = ''
            this.drawDialogVisible = false
            this.loading()
            const color = this.chooseRangeColor + ',' + this.choosePlotColorAlpha
            let r = parseInt(color.slice(1, 3), 16)
            let g = parseInt(color.slice(3, 5), 16)
            let b = parseInt(color.slice(5, 7), 16)
            let a = Math.floor(Number(color.split(',')[1]) * 2.55) ? Math.floor(Number(color.split(',')[1]) * 2.55) : 255
            drawPlotData.setStyle({
                material: global.DC.Namespace.Cesium.Color.fromBytes(r, g, b, a)
            })
            this.$EventBus.$emit('mapClearLayer', {
                layerName: 'treeValAllLayer',
                type: 'VectorLayer'
            })
            this.getRegionList(drawPlotData)
        },
        closeRangeInput () {
            this.inputpopup = false
        },
        getRegionList (type, data) {
        getRegionList ({ customType, positions }) {
            let positionStr = ''
            if (type == 'polyline') {
                data._positions.forEach(item => {
                    positionStr = positionStr + item._lng + ',' + item._lat + ';'
            const color = this.chooseRangeColor + ',' + this.choosePlotColorAlpha
            let r = parseInt(color.slice(1, 3), 16)
            let g = parseInt(color.slice(3, 5), 16)
            let b = parseInt(color.slice(5, 7), 16)
            let a = Math.floor(Number(color.split(',')[1]) * 2.55) ? Math.floor(Number(color.split(',')[1]) * 2.55) : 255
            if (customType == 'polyline') {
                positions.forEach(item => {
                    positionStr += `${item.lng},${item.lat};`
                })
                let coords = global.DC.GeoTools.polylineBuffer(positionStr, 100)
                let coords = global.DC.GeoTools.polylineBuffer(positionStr, this.range)
                let polygon = new global.DC.Polygon(coords)
                let position = ''
                polygon._positions.forEach(item => {
                    position += item._lng + ',' + item._lat + ';'
                polygon.setStyle({
                    material: global.DC.Namespace.Cesium.Color.fromBytes(r, g, b, a)
                })
                position += polygon._positions[0]._lng + ',' + polygon._positions[0]._lat + ';'
                drawPlotLayers.addOverlay(polygon)
                let position = ''
                polygon.positions.forEach(item => {
                    position += `${item.lng},${item.lat};`
                })
                position += polygon.positions[0].lng + ',' + polygon.positions[0].lat + ';'
                positionStr = position
            } else {
                data._positions.forEach(item => {
                    positionStr = positionStr + item._lng + ',' + item._lat + ';'
                positions.forEach(item => {
                    positionStr += `${item.lng},${item.lat};`
                })
                positionStr = positionStr + data._positions[0]._lng + ',' + data._positions[0]._lat + ';'
                positionStr = positionStr + positions[0].lng + ',' + positions[0].lat + ';'
            }
            this.searchTreeData = []
            getRegionList({
                page: 1,
                count: 20,
                range: positionStr
            }).then(res => {
                this.monitoringList = res.data.data.list
                this.searchTreeData = res.data.data
                this.$EventBus.$emit('mapRemoveLayer', {
                    layerName: 'monitoringLayers',
                    type: 'VectorLayer'
                res.data.data.length && res.data.data.forEach(item => {
                    this.$EventBus.$emit('layerPointAdd', {
                        layerName: 'treeValAllLayer',
                        type: "billboard",
                        layerType: 'ClusterLayer',
                        params: {
                            ...item,
                            text: item.name,
                            lng: item.longitude,
                            lat: item.latitude,
                            url: item.status == 1 ? '/img/icon/video.png' : '/img/icon/video-off.png',
                            channelId: item.channelId,
                            status: item.status,
                            disableDepthTestDistance: Number.POSITIVE_INFINITY
                        },
                        incident: this.siteClick,
                        // mouseOverIncident: this.pointMouseOver,
                        // mouseOutIncident: this.pointMouseOut,
                    })
                })
                this.initMonitoringIcon()
            })
        },
        /**
         * @description: 加载面调用接口返回的点数据
         * @return {*}
         */
        initMonitoringIcon () {
            this.monitoringList.forEach(item => {
                this.$EventBus.$emit('layerPointAdd', {
                    layerName: 'monitoringLayers',
                    type: "billboard",
                    params: {
                        name: item.name,
                        lng: item.longitude,
                        lat: item.latitude,
                        alt: 1,
                        url: '/img/icon/video.png',
                        deviceId: item.deviceId,
                        channelId: item.channelId
                    },
                    incident: this.siteClick
                })
            })
        },
        // 保存绘制的线面
        saveDrawInfo () {
            if (this.drawName == '') {
                this.$message({
                    message: '请输入名称',
                    type: 'error'
                })
            } else {
                let drawPositionStr = ''
                let extent = 0
                let width = 0
                if (this.drawType == 1) {
                    // 获取线坐标
                    this.drawPlotData._positions.forEach(item => {
                        drawPositionStr += item._lng + ' ' + item._lat + ','
                    })
                    drawPositionStr = drawPositionStr.slice(0, drawPositionStr.length - 1)
                    // 求线长度
                    let linePosition = []
                    this.drawPlotData._positions.forEach(item => {
                        linePosition.push([item._lng, item._lat])
                    })
                    let line = this.$turf.lineString(linePosition)
                    let length = this.$turf.length(line, { units: 'kilometers' })
                    extent = length.toFixed(3)
                } else {
                    // 获取面坐标
                    this.drawPlotData._positions.forEach(item => {
                        drawPositionStr += item.lng + ' ' + item.lat + ','
                    })
                    drawPositionStr += this.drawPlotData._positions[0]._lng + ' ' + this.drawPlotData._positions[0]._lat
                    // 求面面积
                    let polygonPosition = []
                    this.drawPlotData._positions.forEach(item => {
                        polygonPosition.push([item._lng, item._lat])
                    })
                    polygonPosition.push([this.drawPlotData._positions[0]._lng, this.drawPlotData._positions[0]._lat])
                    let polygon = this.$turf.polygon([polygonPosition])
                    let area = this.$turf.area(polygon)
                    extent = area.toFixed(3)
                }
                this.insertRegionSaveList({ type: this.drawType, positions: drawPositionStr, name: this.drawName, extent: extent, width: this.range, color: this.chooseRangeColor })
                this.drawDialogVisible = false
                this.drawName = ''
                if (drawPlotLayers != null) {
                    drawPlotLayers.clear()
                }
                this.$EventBus.$emit('mapRemoveLayer', {
                    layerName: 'monitoringLayers',
                    type: 'VectorLayer'
                })
            }
        },
        // 取消绘制线面
        cancelSaveDrawInfo () {
            this.drawDialogBeforeClose()
        },
        // type线面类型, positions坐标, name名称, width线宽度, extent线长度或面面积
        insertRegionSaveList (parmas) {
            insertRegionSaveList(parmas).then(res => {
                if (res.data.success) {
                    this.$message({
                        message: '保存成功',
                        type: 'warning'
                    })
                } else {
                    this.$message({
                        message: '保存失败'
                    })
                }
                this.closeLoading()
            })
        },
@@ -518,24 +522,31 @@
                sourceId = node.data.sourceId
            }
            console.log(node, 56)
            const status = node.label == "在线" ? { status: 1 } : node.label == "离线" ? { status: 0 } : {}
            await getTreeDevices({
                deviceId: equipmentNum,
                parentId,
                deptId: this.userInfo.dept_id,
                type,
                sourceId,
                ...status
            }).then(res => {
                data = res.data.data
                data.forEach(item => {
                    item.leaf = !item.parent
                if (data.length) {
                    data.forEach(item => {
                        item.leaf = !item.parent
                    if (!item.longitude && !item.latitude && item.leaf) {
                        item.disabled = true
                    }
                })
                        if (!item.longitude && !item.latitude && item.leaf) {
                            item.disabled = true
                        }
                    })
                data[0].leaf == false && node.level < 2 && this.defaultExpandedKeys.push(data[0].id)
                    data[0].leaf == false && node.level < 2 && this.defaultExpandedKeys.push(data[0].id)
                }
            })
            return resolve(data)
@@ -562,59 +573,23 @@
                siteGd: 600,
            })
            this.$EventBus.$emit('mapClearLayer', {
                layerName: 'treeValLayer',
                type: 'VectorLayer'
            this.$store.commit('SET_VIDEOLISTPOPUP', true)
            this.$store.commit('SET_VIDEOLISTPOPUPDATA', {
                ...node
            })
            this.$EventBus.$emit('mapClearLayer', {
                layerName: 'treeValAllLayer',
                type: 'VectorLayer'
            })
            this.$EventBus.$emit('layerPointAdd', {
                layerName: 'treeValLayer',
                type: "billboard",
                params: {
                    name: node.name,
                    lng: node.longitude,
                    lat: node.latitude,
                    alt: 1,
                    url: node.status == 1 ? '/img/icon/video.png' : '/img/icon/video-off.png',
                    channelId: node.id,
                    status: node.status
                },
                incident: this.siteClick,
                mouseOverIncident: this.pointMouseOver,
                mouseOutIncident: this.pointMouseOut,
                // pointMouseMove: this.pointMouseMove
            })
            getTreeDevicesNearby({ longitude, latitude, mileage: 1 }).then(res => {
                res.data.data.forEach(item => {
                    if (item.longitude && item.latitude && item.channelId != node.id) {
                        this.$EventBus.$emit('layerPointAdd', {
                            layerName: 'treeValAllLayer',
                            type: "billboard",
                            layerType: 'ClusterLayer',
                            params: {
                                ...item,
                                text: item.name,
                                lng: item.longitude,
                                lat: item.latitude,
                                alt: 1,
                                url: item.status == 1 ? '/img/icon/video.png' : '/img/icon/video-off.png',
                                channelId: item.channelId,
                                status: item.status
                            },
                            incident: this.siteClick,
                            mouseOverIncident: this.pointMouseOver,
                            mouseOutIncident: this.pointMouseOut,
                            // pointMouseMove: this.pointMouseMove
                        })
                    }
                })
            var popup = new global.DC.DivForms(global.viewer, {
                domId: 'videoListPopup',
                position: [
                    global.DC.Transform.transformWGS84ToCartesian(
                        new global.DC.Position(
                            Number(node.longitude),
                            Number(node.latitude),
                            0
                        )
                    )
                ]
            })
        },
@@ -657,30 +632,75 @@
        pointMouseOut (e) {
            this.$store.commit('SET_VIDEOLISTPOPUP', false)
        },
        // 获取设备列表
        getEquipmentAll (params, layerName) {
            this.loading()
            this.$EventBus.$emit('mapClearLayer', {
                layerName: 'treeValAllLayer',
                type: 'VectorLayer'
            })
            initMapPosition()
            getEquipmentAll({ ...params, deptId: this.userInfo.dept_id }).then(res => {
                if (params.type == 1 && res.data.data) {
                    res.data.data.forEach(item => {
                        if (item.longitude && item.latitude) {
                            this.$EventBus.$emit('layerPointAdd', {
                                layerName: 'treeValAllLayer',
                                type: "billboard",
                                layerType: 'ClusterLayer',
                                params: {
                                    ...item,
                                    text: item.name,
                                    lng: item.longitude,
                                    lat: item.latitude,
                                    url: item.status == 1 ? '/img/icon/video.png' : '/img/icon/video-off.png',
                                    channelId: item.channelId,
                                    status: item.status,
                                    disableDepthTestDistance: Number.POSITIVE_INFINITY
                                },
                                incident: this.siteClick,
                                // mouseOverIncident: this.pointMouseOver,
                                // mouseOutIncident: this.pointMouseOut,
                            })
                        }
                    })
                }
                this.closeLoading()
            })
        },
        loading () {
            loading = this.$loading({
                lock: true,
                text: '拼命加载中',
                spinner: 'el-icon-loading',
                background: 'rgba(0, 0, 0, 0.2)'
            })
        },
        closeLoading () {
            if (loading != null) {
                setTimeout(() => {
                    loading.close()
                }, 1000)
            }
        },
    },
    destroyed () {
        this.$EventBus.$emit('mapRemoveLayer', {
            layerName: 'monitoringLayers',
            type: 'VectorLayer'
        })
        this.$EventBus.$emit('mapRemoveLayer', {
            layerName: 'searchLayer',
            type: 'VectorLayer'
        })
        this.$EventBus.$emit('mapRemoveLayer', {
            layerName: 'treeValLayer',
            type: 'VectorLayer'
        })
        this.$store.commit('SET_VIDEOLISTPOPUP', false)
        loading.close()
        this.$EventBus.$emit('mapRemoveLayer', {
            layerName: 'treeValAllLayer',
            type: 'VectorLayer'
        })
        // graphicLayer.destroy()
        this.$parent.$parent.$parent.resize('0px')