| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427 |
- <template>
- <div class="widget-monitorTree" ref="widget-monitorTree">
- <div class="content">
- <div class="header">
- <!-- <div class="title">设备监测树</div> -->
- <el-input placeholder="设备名称搜索" v-model="filterText" size="mini" clearable>
- <el-button slot="append" icon="el-icon-search"></el-button>
- </el-input>
- </div>
- <div class="statistic">
- <div class="deviceTypeGroup">
- <el-tree
- class="filter-tree"
- show-checkbox
- :data="treeData"
- :props="defaultProps"
- default-expand-all
- node-key="id"
- :default-checked-keys="defaultCheckedKeys"
- :filter-node-method="filterNode"
- @check="getCheckList()"
- @node-click="handleTreeNodeClick"
- ref="tree"
- >
- <span slot-scope="{ node }">
- {{ node.label }}
- <img v-if="setNodeImg(node)" :src="`${setNodeImg(node)}`" style="width: 16px; height: 16px" />
- </span>
- </el-tree>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script lang="ts">
- import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
- import { getLatAndLon } from '@/views/groupPage/util'
- import { getZhgdCameraData, getZhgdEquipmentData, getZhgdHelmetData, getZhgdGPSData } from '@/views/groupPage/apis'
- import deviceInfo from '@/views/groupPage/districtPageModules/customTools/infoComponents/deviceInfo.vue'
- const Cesium = (window as any).Cesium
- let customDataSource = new Cesium.CustomDataSource('monitorTree')
- let timeInterval = null
- let handler = null
- //设备监测树
- @Component({ name: 'monitorTree' })
- export default class monitorTree extends Vue {
- @Watch('filterText')
- onChangeMethod(val) {
- let target = this.$refs.tree as any
- target.filter(val)
- }
- @Watch('deviceCheckList', { deep: true })
- onChangeCheckListMethod(val) {
- this.showMapPoint()
- this.$store.state.bigScreen.monitorTreeCheckHistory = []
- val.forEach((item) => {
- this.$store.state.bigScreen.monitorTreeCheckHistory.push(item.id)
- })
- }
- @Watch('treeData', { deep: true })
- onChangeTreeDataMethod() {
- this.setCheckInfo()
- }
- @Watch('currentDeviceShow')
- onChangeCurrentDeviceShow(n) {
- if (n) this.initInfoPop(n, Cesium.Cartesian3.fromDegrees(n.position[0], n.position[1]))
- }
- get historyInfo() {
- return this.$store.state.bigScreen.monitorTreeCheckHistory
- }
- get currentDeviceShow() {
- return this.$store.state.bigScreen.currentDeviceShow
- }
- viewer
- //参数
- deviceCheckList = []
- filterText = ''
- treeData = []
- defaultProps = { children: 'children', label: 'name' }
- defaultCheckedKeys = []
- mounted() {
- this.initCom()
- //定时刷新
- if (timeInterval) {
- clearInterval(timeInterval)
- timeInterval = null
- }
- timeInterval = setInterval(() => {
- this.initCom()
- }, 10000) //600000
- }
- initCom() {
- if (!this.$store.state.bigScreen.isInitViewer) return
- let init = (window as any).viewer
- if (init) {
- this.viewer = init
- this.clearDataSource()
- this.viewer.dataSources.add(customDataSource)
- this.getData()
- } else {
- console.error('viewer未初始化')
- }
- }
- //获取监测设备数据
- async getData() {
- //摄像头
- const cameraRes = await getZhgdCameraData({})
- let cameras = cameraRes.result.map((item) => {
- return {
- ...item,
- status: item.status == 0 ? '离线' : '在线',
- type: item.type == 1 ? '球机' : '枪机',
- deviceType: '摄像头'
- }
- })
- //监控设备
- const monitorRes = await getZhgdEquipmentData({})
- let monitors = monitorRes.result.map((item) => {
- item.zhgdEquipment.status = item.zhgdEquipment.status == 0 ? '离线' : '在线'
- item.zhgdEquipment.deviceType = '监控设备'
- item.zhgdEquipment.name = item.zhgdEquipment.equipment_name
- item.zhgdEquipment.latitude = item.zhgdEquipment.lat
- item.zhgdEquipment.longitude = item.zhgdEquipment.lon
- return item.zhgdEquipment
- })
- //安全帽
- const helmetRes = await getZhgdHelmetData({})
- let helmets = helmetRes.result.map((item) => {
- return {
- ...item,
- deviceType: '安全帽',
- latitude: item.lat,
- longitude: item.lon,
- name: item.person_id,
- status: item.status == 1 ? '未激活' : item.status == 2 ? '离线' : item.status == 3 ? '在线' : '无'
- }
- })
- //GPS设备
- // const gpsRes = await getZhgdGPSData({})
- this.treeData = [
- { name: '智慧工地摄像头', children: cameras },
- { name: '智慧工地监控设备', children: monitors },
- // { name: '智慧工地GPS', children: [] },
- { name: '智慧工地安全帽', children: helmets }
- ]
- }
- setStatusIconColor(type) {
- let color = type === '在线' ? '#2BA7FF' : type === '离线' ? 'grey' : type === '正常' ? '#2BA7FF' : 'red'
- return 'background-color:' + color
- }
- //节点过滤
- filterNode(value, data) {
- if (!value) return true
- return data.name.indexOf(value) !== -1
- }
- setNodeImg(node) {
- let iconSrc
- return iconSrc
- }
- handleTreeNodeClick(data) {
- if (!data.longitude || !data.latitude) {
- this.$message.info('暂无位置信息')
- return
- }
- let entity = customDataSource.entities.getById(data.name)
- let item = {
- name: data.name,
- id: data.id,
- position: [Number(data.longitude), Number(data.latitude)],
- info: data
- }
- this.viewer.flyTo(entity).then(() => {
- this.initInfoPop(item, Cesium.Cartesian3.fromDegrees(item.position[0], item.position[1]))
- })
- }
- getCheckList() {
- this.deviceCheckList = (this.$refs.tree as any).getCheckedNodes().filter((item) => !item.children)
- }
- setCheckInfo() {
- let checkedList = []
- let tempCheckList = this.treeData
- .map((item, index) => {
- if (item.children) {
- item.children.forEach((child) => {
- if (this.historyInfo != null) {
- if (child.id && this.historyInfo.some((id) => id == child.id)) {
- checkedList.push(child.id)
- }
- } else {
- checkedList.push(child.id)
- }
- })
- }
- return item.children
- })
- .flat()
- let temp = []
- tempCheckList.forEach((item) => {
- if (checkedList.some((id) => id == item.id)) {
- temp.push(item)
- }
- })
- this.deviceCheckList = temp
- this.$nextTick(() => {
- this.defaultCheckedKeys = checkedList
- this.$store.state.bigScreen.monitorTreeCheckHistory = this.defaultCheckedKeys
- })
- }
- showMapPoint() {
- if (Cesium.defined(customDataSource)) {
- customDataSource.entities.removeAll()
- }
- for (let index = 0; index < this.deviceCheckList.length; index++) {
- const item = this.deviceCheckList[index]
- if (!item.longitude || !item.latitude) continue
- const infoData = {
- id: item.id,
- name: item.name,
- position: [Number(item.longitude), Number(item.latitude)],
- info: item
- }
- this.addEntity(infoData)
- }
- this.activeMapEvent()
- }
- addEntity(options) {
- let image = this.iconSelect(options.info.deviceType)
- const position = Cesium.Cartesian3.fromDegrees(options.position[0], options.position[1], 0)
- var bottomPosition = Cesium.Cartographic.fromCartesian(position)
- var entity = new Cesium.Entity({
- id: options.name,
- type: 'deviceInfo',
- name: options.name,
- show: true,
- position: Cesium.Cartographic.toCartesian(bottomPosition),
- billboard: {
- sizeInMeters: false,
- image: image,
- width: 40,
- height: 65,
- // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
- verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
- horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
- disableDepthTestDistance: 9999999
- },
- info: options
- })
- customDataSource.entities.add(entity)
- }
- iconSelect(type) {
- let icon = ''
- switch (type) {
- case '摄像头':
- icon = require('@/views/groupPage/images/设备/摄像头.png')
- break
- case '监控设备':
- icon = require('@/views/groupPage/images/设备/监控设备.png')
- break
- case '安全帽':
- icon = require('@/views/groupPage/images/设备/安全帽.png')
- break
- }
- return icon
- }
- activeMapEvent() {
- const that = this
- handler = new Cesium.ScreenSpaceEventHandler(this.viewer.canvas)
- handler.setInputAction(
- function (movement) {
- var pickedObject = this.viewer.scene.pick(movement.position)
- const coordinate = getLatAndLon(this.viewer, movement)
- const position = Cesium.Cartesian3.fromDegrees(coordinate.longitude, coordinate.latitude, coordinate.altitude)
- // 使用时,最好利用pickPositionSupported判断一下浏览器是否支持模型高度拾取
- if (this.viewer.scene.pickPositionSupported && Cesium.defined(pickedObject)) {
- if (pickedObject.id.type === 'deviceInfo') {
- that.initInfoPop(pickedObject.id.info, position)
- }
- } else {
- }
- }.bind(this),
- Cesium.ScreenSpaceEventType.LEFT_CLICK
- )
- }
- initInfoPop(data, position) {
- let deviceInfoConstructor = Vue.extend(deviceInfo)
- const deviceInfoModule = new deviceInfoConstructor({
- data: {
- info: data.info,
- id: data.id.toString(),
- position
- },
- store: this.$store
- }).$mount()
- }
- clearDataSource() {
- if (Cesium.defined(customDataSource)) {
- customDataSource.entities.removeAll()
- this.viewer.dataSources.remove(customDataSource)
- }
- if (timeInterval) {
- clearInterval(timeInterval)
- timeInterval = null
- }
- }
- beforeDestroy() {}
- }
- </script>
- <style lang="scss" scoped>
- .animate__flipInX,
- .animate__flipOutX {
- animation-duration: 3s; //动画持续时间
- animation-delay: 0s; //动画延迟时间
- }
- .widget-monitorTree {
- width: 100%;
- height: 100%;
- color: #eee;
- //font
- font-family: Source Han Sans CN;
- & ::placeholder {
- color: rgba(255, 255, 255, 0.3);
- }
- .content {
- width: 2.1875rem /* 420/192 */;
- height: 1.979167rem /* 380/192 */;
- // background: linear-gradient(0deg, rgba(2, 20, 37, 0.56) 0%, #072643 100%);
- .header {
- height: 0.208333rem /* 40/192 */;
- margin: 0 0.052083rem 0 0.052083rem;
- padding: 0.026042rem /* 5/192 */;
- // border-bottom: 1px solid rgba(255, 255, 255, 0.1);
- display: flex;
- align-items: center;
- justify-content: space-between;
- .title {
- font-size: 0.083333rem /* 16/192 */;
- font-weight: 500;
- color: #2ba7ff;
- white-space: nowrap;
- }
- .close {
- display: flex;
- align-items: center;
- height: 100%;
- color: rgba(138, 211, 253, 1);
- font-size: 0.09375rem /* 18/192 */;
- cursor: pointer;
- }
- /deep/ .el-input__inner {
- background-color: rgb(9, 48, 84);
- border: none;
- color: #eee;
- height: 0.177083rem /* 34/192 */;
- font-size: 0.072917rem /* 14/192 */;
- }
- /deep/ .el-input-group__append {
- background-color: rgb(9, 48, 84);
- border: none;
- }
- /deep/ .el-icon-search:before {
- color: rgba(138, 211, 253, 0.3);
- font-size: 0.09375rem /* 18/192 */;
- }
- }
- .statistic {
- display: flex;
- flex-flow: column;
- width: 100%;
- height: 100%;
- margin-top: 0.052083rem /* 10/192 */;
- .deviceTypeGroup {
- width: 100%;
- height: calc(100% - 0.104167rem /* 20/192 */);
- overflow: auto;
- /deep/ .el-tree {
- background: transparent;
- color: #8eb2ce;
- font-size: 0.083333rem /* 16/192 */;
- .el-tree-node__content {
- background-color: transparent;
- }
- .el-tree-node__content:hover {
- background-color: rgb(62, 70, 112);
- }
- // div[role='group'] > .el-tree-node {
- // width: 50%;
- // float: left;
- // }
- .el-tree-node.is-current > .el-tree-node__content {
- background: rgba(22, 119, 255, 0.1);
- border-right: 3px solid #1677ff;
- color: #4b95fe;
- /deep/ .el-tree-node__expand-icon {
- color: rgb(0, 112, 255);
- }
- /deep/ .is-leaf {
- color: rgba(0, 0, 0, 0);
- }
- }
- }
- .el-checkbox {
- color: #fff;
- margin: 0.052083rem /* 10/192 */ 0;
- }
- /deep/ .el-checkbox__inner {
- background: #0a1525;
- border-color: rgba(3, 109, 190, 1);
- }
- /deep/ .el-checkbox__inner::after {
- border: 2px solid rgba(17, 156, 255, 1);
- border-left: 0;
- border-top: 0;
- }
- /deep/ .el-checkbox__input.is-checked .el-checkbox__inner {
- background: #0a1525;
- border-color: rgba(3, 109, 190, 1);
- }
- /deep/ .el-checkbox__input.is-checked + .el-checkbox__label {
- color: #fff;
- }
- }
- }
- }
- }
- </style>
|