Files
dvcp_v2_webapp/packages/device/IntelligentSecurity/components/deviceSlider.vue

355 lines
8.1 KiB
Vue
Raw Normal View History

2022-02-18 13:54:47 +08:00
<template>
<section class="deviceSlider">
<div class="mainPane" v-if="show">
<div flex overview>
<b>监控设备</b>
<div>
<div>设备总数{{ overview.total }}</div>
<div flex>在线设备<p v-text="overview.online"/></div>
</div>
<el-progress type="circle" :width="40" :percentage="overview.percent" color="#19D286" :stroke-width="4"/>
</div>
<div flex search>
<el-select v-model="search.bind" size="mini" placeholder="全部" clearable @change="onChange">
<el-option v-for="(op,i) in dict.getDict('deviceStatus')" :key="i" :value="op.dictValue"
:label="op.dictName"/>
</el-select>
2022-03-24 15:18:01 +08:00
<el-input
2022-03-28 14:56:24 +08:00
v-model="search.name"
size="mini"
placeholder="设备名称"
v-throttle="handleTreeFilter"
prefix-icon="el-icon-search"
@clear="search.name = '', handleTreeFilter()" clearable/>
2022-02-18 13:54:47 +08:00
</div>
2022-06-28 09:15:10 +08:00
<div title>
<div>设备列表</div>
<el-button type="text" icon="iconfont iconResetting" @click="updateDev" size="mini" :loading="btnLoading">刷新</el-button>
</div>
2022-02-18 13:54:47 +08:00
<div fill class="deviceList">
2022-04-21 16:11:45 +08:00
<el-tree ref="deviceTree" highlight-current :render-content="renderItem" :data="treeData" :props="propsConfig"
2022-03-28 14:56:24 +08:00
@node-click="handleNodeClick" @node-contextmenu="nodeContextmenu"
:filter-node-method="handleFilter"/>
<ul
2022-04-21 16:11:45 +08:00
v-if="isShowMenu && menuInfo.node.type==1 && permissions('video_config')"
class="el-dropdown-menu el-popper"
:style="{top: menuInfo.y + 'px', left: menuInfo.x + 'px', position: 'fixed', zIndex: 2023}"
x-placement="top-end">
2022-03-28 14:56:24 +08:00
<li class="el-dropdown-menu__item" @click="handleTreeCommand('edit', menuInfo.node)">修改名称</li>
<li class="el-dropdown-menu__item" @click="handleTreeCommand('locate', menuInfo.node)">地图标绘</li>
</ul>
2022-02-18 13:54:47 +08:00
</div>
</div>
<div class="rightBtn" :class="{show}" @click="handleShow">
<i class="iconfont iconArrow_Right"/>
</div>
</section>
</template>
<script>
export default {
name: "deviceSlider",
props: {
show: Boolean,
2022-06-28 09:15:10 +08:00
instance: Function,
2022-02-18 13:54:47 +08:00
dict: Object,
2022-03-28 09:54:18 +08:00
permissions: Function,
2022-06-28 09:15:10 +08:00
renderItem: Function,
2022-02-18 13:54:47 +08:00
},
computed: {
overview() {
let total = this.list?.length || 0,
online = this.list?.filter(e => e.deviceStatus == 1)?.length || 0
return {
total, online,
percent: Math.ceil(online / total * 100) || 0
}
},
propsConfig() {
return {
label: 'name',
children: 'children'
}
},
treeData() {
let {list, noArea, staData} = this
let meta = [staData?.reduce((t, e) => {
return t.type <= e.type ? t : e
}, {name: '读取中...'})]
meta.map(p => this.addChild(p, [...staData, ...list].map(s => ({
...s,
parentId: s.areaId || s.parent_id
}))))
return [...meta, {
id: 'no_area',
name: '未知区划',
children: noArea
}]
}
},
data() {
return {
list: [],
noArea: [],
staData: [],
name: '',
2022-03-25 11:29:42 +08:00
isShowMenu: false,
2022-02-18 13:54:47 +08:00
search: {
bind: ''
2022-03-25 11:29:42 +08:00
},
menuInfo: {
x: '',
y: '',
node: {}
2022-06-28 09:15:10 +08:00
},
btnLoading: false,
2022-02-18 13:54:47 +08:00
}
},
methods: {
handleShow() {
this.$emit('update:show', !this.show)
},
2022-03-25 11:29:42 +08:00
bindEvent() {
this.isShowMenu = false
},
2022-02-18 13:54:47 +08:00
getDevices() {
2022-06-28 09:15:10 +08:00
this.instance.post(`/app/appzyvideoequipment/tree`, null, {
params: {
size: 999
}
2022-02-18 13:54:47 +08:00
}).then(res => {
if (res?.data) {
this.staData = res.data.count
this.list = res.data.list
this.noArea = res.data.noArea
this.$emit('list', this.list)
}
})
},
2022-03-25 11:29:42 +08:00
2022-06-28 09:15:10 +08:00
updateDev() {
this.btnLoading = true
this.instance.post(`/app/appzyvideoequipment/sync`, null, {
timeout: 1000000
}).then(res => {
if (res.code == 0) {
this.$message.success('更新成功')
this.getDevices()
}
this.btnLoading = false
}).catch(() => {
this.btnLoading = false
})
},
2022-03-28 14:56:24 +08:00
handleTreeCommand(e, node) {
2022-03-25 11:29:42 +08:00
this.$emit('treeCommand', {
type: e,
node
})
},
nodeContextmenu(e, node) {
this.isShowMenu = true
let y = e.y + 6
if (y + 202 > document.body.clientHeight) {
y = y - 202
}
this.menuInfo = {
x: e.x + 16, y,
node
}
},
2022-02-18 13:54:47 +08:00
handleNodeClick(data) {
2022-03-25 11:41:09 +08:00
this.isShowMenu = false
2022-02-18 13:54:47 +08:00
this.$emit('select', data)
},
handleFilter(v, data) {
if (!v) {
return !this.search.bind ? true : data.deviceStatus === this.search.bind
}
2022-03-28 14:56:24 +08:00
return data?.name?.indexOf(v) > -1 && (!this.search.bind ? true : data.deviceStatus === this.search.bind)
2022-02-18 13:54:47 +08:00
},
2022-03-24 15:18:01 +08:00
handleTreeFilter() {
this.$refs.deviceTree?.filter(this.search.name)
2022-02-18 13:54:47 +08:00
},
2022-03-28 14:56:24 +08:00
onChange() {
2022-02-18 13:54:47 +08:00
this.$refs.deviceTree?.filter(this.search.name)
2022-06-28 09:15:10 +08:00
},
2022-12-01 09:35:20 +08:00
2022-02-18 13:54:47 +08:00
},
2022-06-28 09:15:10 +08:00
2022-02-18 13:54:47 +08:00
created() {
2022-06-28 09:15:10 +08:00
this.$dict.load("deviceStatus").then(()=>{
this.getDevices()
})
2022-03-25 11:29:42 +08:00
},
2022-03-28 14:56:24 +08:00
mounted() {
2022-03-25 11:29:42 +08:00
document.querySelector('html').addEventListener('click', this.bindEvent)
2022-02-18 13:54:47 +08:00
}
}
</script>
<style lang="scss" scoped>
.deviceSlider {
display: flex;
align-items: center;
flex-shrink: 0;
color: #fff;
2022-03-25 11:29:42 +08:00
overflow: hidden;
2022-02-18 13:54:47 +08:00
div[flex] {
display: flex;
align-items: center;
}
2022-03-25 11:29:42 +08:00
.deviceList {
overflow: auto;
2022-12-01 09:35:20 +08:00
:deep( .el-tree ){
2022-03-25 11:29:42 +08:00
width: -webkit-fit-content;
width: -moz-fit-content;
width: fit-content;
min-width: 100%;
}
2022-03-28 14:56:24 +08:00
2022-03-25 11:29:42 +08:00
&::-webkit-scrollbar {
2022-03-28 14:56:24 +08:00
width: 10px;
2022-03-25 11:29:42 +08:00
height: 15px;
}
2022-03-28 14:56:24 +08:00
2022-03-25 11:29:42 +08:00
&::-webkit-scrollbar-thumb {
box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.2);
background: #535353;
}
2022-03-28 14:56:24 +08:00
2022-03-25 11:29:42 +08:00
&::-webkit-scrollbar-track {
box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.2);
background: #fff;
}
}
2022-02-18 13:54:47 +08:00
div[fill] {
flex: 1;
min-width: 0;
min-height: 0;
}
.mainPane {
width: 280px;
height: 100%;
background: #333C53;
display: flex;
flex-direction: column;
padding-top: 16px;
overflow: hidden;
box-sizing: border-box;
b {
font-size: 18px;
}
div[overview], div[search] {
box-sizing: border-box;
font-size: 12px;
justify-content: space-between;
padding: 0 16px;
gap: 4px;
margin-bottom: 16px;
2022-12-01 09:35:20 +08:00
:deep(.el-input__inner ){
2022-02-18 13:54:47 +08:00
color: #fff;
}
}
div[title] {
height: 28px;
background: #3E4A69;
padding: 0 16px;
line-height: 28px;
2022-06-28 09:15:10 +08:00
display: flex;
justify-content: space-between;
align-items: center;
2022-12-01 09:35:20 +08:00
:deep( .el-button ){
2022-06-28 09:15:10 +08:00
padding: 0 4px;
height: 28px;
background: #3E4A69;
}
2022-12-01 09:35:20 +08:00
:deep( .el-button:hover ){
2022-06-28 09:15:10 +08:00
border: none;
}
2022-02-18 13:54:47 +08:00
}
2022-12-01 09:35:20 +08:00
:deep(.deviceList ){
2022-02-18 13:54:47 +08:00
padding: 0 8px;
.el-scrollbar {
height: 100%;
.el-scrollbar__wrap {
box-sizing: content-box;
padding-bottom: 17px;
}
}
}
2022-12-01 09:35:20 +08:00
:deep( .el-progress__text), p {
2022-02-18 13:54:47 +08:00
color: #19D286;
}
2022-12-01 09:35:20 +08:00
:deep( .el-input__inner ){
2022-02-18 13:54:47 +08:00
background: #282F45;
border: none;
}
2022-12-01 09:35:20 +08:00
:deep( .el-tree ){
2022-02-18 13:54:47 +08:00
background: transparent;
color: #fff;
2022-04-21 16:11:45 +08:00
.el-tree-node__content {
background: transparent!important;
}
2022-06-14 09:11:46 +08:00
.el-tree-node__children .is-current > .el-tree-node__content {
2022-04-21 16:11:45 +08:00
background: linear-gradient(90deg, #299FFF 0%, #0C61FF 100%)!important;
}
.el-tree-node__content:hover {
background: transparent;
}
.el-tree-node__content {
height: 32px;
2022-02-18 13:54:47 +08:00
}
}
2022-12-01 09:35:20 +08:00
:deep( .el-input__icon ){
2022-02-18 13:54:47 +08:00
color: #89b;
}
}
.rightBtn {
width: 16px;
height: 80px;
background: url("https://cdn.cunwuyun.cn/monitor/drawerBtn.png");
color: #fff;
display: flex;
align-items: center;
justify-content: center;
.iconfont {
transition: transform 0.2s;
}
&.show > .iconfont {
transform: rotate(180deg);
}
}
}
</style>