<template>
|
<b-card class="mx-4 mt-4 " style="height: 85vh;">
|
<div>
|
<h4 class="font-weight-bold py-3 mb-2">
|
<router-link to="/">
|
<span class="font-weight-bold" style="color:#4E5155">布控任务 /</span>
|
</router-link>
|
<span class="text-muted font-weight-light">{{$route.query.isEdit?'编辑布控':'新增布控'}}</span>
|
</h4>
|
<div class="flex-box out-div p10">
|
<div class="left-div">
|
<span>布控名称:</span>
|
<el-input
|
placeholder="内容"
|
v-model="controlName"
|
clearable>
|
</el-input>
|
<div class="mt30">
|
<span>布控时间</span>
|
<div class="">
|
<el-date-picker
|
:clearable="false"
|
v-model="controlTime"
|
type="datetimerange"
|
range-separator="至"
|
style="width:100%"
|
format="yyyy/MM/dd HH:mm:ss"
|
value-format="yyyy/MM/dd HH:mm:ss"
|
:default-time="['00:00:00', '23:59:59']"
|
:picker-options="pickerOptions"
|
start-placeholder="开始日期"
|
end-placeholder="结束日期">
|
</el-date-picker>
|
</div>
|
</div>
|
<div class="mt30">
|
<span>对比阈值</span>
|
<div>
|
<el-input-number
|
v-model="thresholdNum"
|
controls-position="right"
|
:min="1" :max="100">
|
</el-input-number>
|
</div>
|
|
</div>
|
|
</div>
|
<div class="right-div">
|
<div class="flex-row-between">
|
<div class="flex-row-left" style="width:50%">
|
<div class="col-md-3 d-flex">
|
<div
|
class="table-switch-btn active"
|
:class="tabType==='map'?'active':''"
|
@click="tabType='map'"
|
v-show="tabType==='tree'"
|
>
|
<i class="fas fa-map" title="切换到地图"></i>
|
</div>
|
<div
|
class="table-switch-btn active"
|
:class="tabType==='tree'?'active':''"
|
@click="tabType='tree'"
|
v-show="tabType==='map'"
|
>
|
<i class="fas fa-list-ul" title="切换到列表"></i>
|
</div>
|
<div class="flex-center">
|
<span class="fb f16">布控范围</span>
|
</div>
|
</div>
|
<div class="col-md-9 d-flex">
|
<div v-if="tabType==='tree'" class="mr20 col-md-7">
|
<el-input
|
v-model="searchName"
|
placeholder="集群名称/节点名称/设备名称">
|
</el-input>
|
</div>
|
<div v-if="tabType==='map'" class="mr20 col-md-7">
|
<imput-auto ref="autoInput" :selectList="allDevices" @selectDevice="selectDevice"></imput-auto>
|
</div>
|
<el-button type="primary" @click.native="searchByName">搜索</el-button>
|
</div>
|
</div>
|
<div class="flex-row-right" v-if="$route.query.isEdit">
|
<el-button type="primary" @click.native="stopTask">停止布控</el-button>
|
<el-button type="info" @click.native="delTask">删除布控</el-button>
|
</div>
|
</div>
|
<div class="map-tree">
|
<div v-show="tabType==='tree'" class="flex-row-between">
|
<div class="right-tree-all">
|
<div class="mt30">
|
<div class="fb f16">
|
<el-checkbox v-model="checkAll">全部</el-checkbox>
|
</div>
|
<tree-all
|
ref="treeall"
|
:data="treeDataAll"
|
@currentNode="currentNode"
|
:isOpenAll="true">
|
</tree-all>
|
</div>
|
</div>
|
<div class="select-node">
|
<div>
|
<div class="mt30">
|
<span class="fb f16">已选:</span>
|
<selected-tree
|
ref="treeselect"
|
:data="selectNode"
|
@delSelected="delSelected"
|
:isOpenAll="true">
|
</selected-tree>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div v-if="tabType==='map'">
|
<div class="map">
|
<view-map ref="map" :allDevices="allDevices"></view-map>
|
</div>
|
</div>
|
</div>
|
|
</div>
|
</div>
|
<div class="save-cancel">
|
<div class="flex-center">
|
<el-button type="primary" @click.native="save">保存</el-button>
|
<el-button type="info" @click.native="$router.push({path:'/',query:{}})">取消</el-button>
|
</div>
|
|
</div>
|
</div>
|
</b-card>
|
</template>
|
<script>
|
import {
|
Input, DatePicker, Button, InputNumber, Checkbox
|
} from 'element-ui'
|
import treeAll from './components/ShareTree'
|
import selectedTree from './components/selectedTree'
|
import ViewMap from '../Home/components/mapDeviceList'
|
import imputAuto from './components/inputAutoComplete'
|
import {
|
getClusterDeviceTree, addTask, findOneTask, updateTask,
|
delTask, stopTask
|
} from '@/server/task.js'
|
let allMinDate = ''
|
export default {
|
props: {
|
|
},
|
components: {
|
elInput: Input,
|
elDatePicker: DatePicker,
|
elButton: Button,
|
elInputNumber: InputNumber,
|
elCheckbox: Checkbox,
|
treeAll,
|
selectedTree,
|
ViewMap: ViewMap,
|
imputAuto: imputAuto
|
},
|
data() {
|
return {
|
pickerOptions: {
|
disabledDate(time) {
|
if (allMinDate) {
|
return (
|
time.getTime() < Date.now() ||
|
time < new Date(allMinDate.getTime() - 3600 * 1000 * 24 * 90) ||
|
time > new Date(allMinDate.getTime() + 3600 * 1000 * 24 * 90)
|
)
|
}
|
return time.getTime() < Date.now()
|
},
|
onPick({ maxDate, minDate }) {
|
allMinDate = maxDate
|
}
|
|
},
|
/** 布控名称 */
|
controlName: '',
|
/** 布控时间 */
|
controlTime: [],
|
/** 阈值 */
|
thresholdNum: 60,
|
/** 地图上设备树是否展开 */
|
isOpenTree: true,
|
/** 树节点 */
|
currentItem: {id: '0', type: '1', name: '集群设备'},
|
/** 设备集群树数据 */
|
colonyData: [],
|
/** 展示类型 */
|
tabType: 'tree',
|
searchName: '',
|
/** 全部集群 */
|
treeDataAll: [],
|
/** 勾选全部 */
|
checkAll: false,
|
/** 勾选的节点 */
|
selectNode: [],
|
/** 存储的布控任务信息 */
|
ctrolObj: {},
|
/** 存储勾选的所有设备,用以传递到地图上 */
|
allDevices: []
|
}
|
},
|
methods: {
|
getFormatDate(fmt) {
|
/* eslint-disable */
|
Date.prototype.Format = function(fmt) { // author: meizz
|
var o = {
|
'M+': this.getMonth() + 1, // 月份
|
'd+': this.getDate(), // 日
|
'h+': this.getHours(), // 小时
|
'm+': this.getMinutes(), // 分
|
's+': this.getSeconds(), // 秒
|
'q+': Math.floor((this.getMonth() + 3) / 3), // 季度
|
'S': this.getMilliseconds() // 毫秒
|
}
|
if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length)) }
|
for (var k in o) {
|
if (new RegExp('(' + k + ')').test(fmt)) { fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))}
|
}
|
return fmt
|
}
|
return (new Date()).Format("yyyy-MM-dd hh:mm:ss")
|
},
|
searchByName(){
|
if(this.tabType === 'tree'){
|
this.$refs.treeall.handleSearch(this.searchName)
|
}
|
if(this.tabType === 'map'){
|
let areaName = this.$refs.autoInput.backInput()
|
console.log(areaName,'areaName searchByName')
|
if(areaName === ''){
|
this.$refs.map.cancelActive()
|
}else{
|
let areaDevice = this.allDevices.filter((i)=>{
|
if(i.address && i.address !== null){
|
return (i.address.toLowerCase().indexOf(areaName.toLowerCase()) === 0)
|
}else{
|
return false
|
}
|
})
|
console.log(areaDevice,'areaDevice searchByName')
|
this.$refs.map.setActive(areaDevice)
|
}
|
}
|
},
|
/** 获取设备树的id */
|
getTreeId(obj,arr){
|
arr.push(obj.id)
|
if(obj.child && obj.child.length !== 0 ){
|
obj.child.forEach((item,index)=>{
|
this.getTreeId(item,arr)
|
})
|
}
|
},
|
/** 获取所有节点的集合 */
|
getTreeNode(obj,arr){
|
arr.push(obj)
|
if(obj.child && obj.child.length !== 0 ){
|
obj.child.forEach((item,index)=>{
|
this.getTreeNode(item,arr)
|
})
|
}
|
},
|
/** 判断是否有parentId同时将自身赋值到children上 */
|
haveParent(item){
|
if(item.parentId){
|
for(let node of allNodes){
|
if(node.id === item.parentId){
|
let arr = []
|
arr.push(item)
|
this.$set(node,'child',arr)
|
}
|
}
|
}
|
},
|
/** 获取选择的节点 */
|
currentNode(nodes,checkNode,checkNodes){
|
let tree2 = JSON.parse(JSON.stringify(nodes))
|
console.log(nodes,'nodes',checkNode,checkNodes,'checkNodes')
|
const allNodes = []
|
tree2.forEach(i=>{
|
this.getTreeNode(i,allNodes)
|
})
|
let parentObj = []
|
const haveParent = item =>{
|
if(item.parentId && item.parentId !== null){
|
for(let node of allNodes){
|
if(node.id === item.parentId){
|
let arr = []
|
let childs = []
|
arr.push(item)
|
if(node.child && node.child.length !== 0){
|
childs = node.child.filter(item =>{
|
return item.isCheck
|
})
|
}
|
this.$set(node,'isCheck',true)
|
this.$set(node,'child',childs)
|
// console.log(node,'children',childs)
|
haveParent(node)
|
}
|
}
|
}else{
|
if(parentObj.length !== 0){
|
for(let a of parentObj){
|
if(a.id === item.id){
|
continue
|
}else{
|
parentObj.push(item)
|
}
|
}
|
}else{
|
parentObj.push(item)
|
}
|
|
}
|
}
|
if(checkNodes && checkNodes.length !== 0){
|
for(let item of checkNodes){
|
// console.log(item,'item')
|
haveParent(item)
|
}
|
}
|
// console.log(parentObj,'parentObj')
|
let newArr = []
|
parentObj.forEach((i,index)=>{
|
if(index === 0){
|
newArr.push(i)
|
}else{
|
newArr.forEach((j,index)=>{
|
let ishave = false
|
if(j.id === i.id){
|
ishave = true
|
}
|
if(newArr.length-1 === index){
|
/** 说明已经判断到最后一个了 */
|
if(!ishave){
|
newArr.push(i)
|
}
|
}
|
})
|
}
|
})
|
console.log(newArr,'parentObj newArr')
|
|
this.selectNode = newArr
|
const list = []
|
const _haveParent = data =>{
|
for(let item of nodes){
|
|
}
|
}
|
const _haveCheck = nodes =>{
|
for(let item of nodes){
|
if(item.isCheck){
|
list.push(item)
|
}else if(item.child){
|
_haveCheck(item.child)
|
}
|
}
|
}
|
_haveCheck(nodes)
|
console.log(list,'list _haveCheck')
|
|
},
|
haveChild(node) {
|
if (node && node.child && node.child.length !== 0) {
|
node.child.forEach((item, index) => {
|
this.haveChild(item)
|
})
|
}else{
|
return node.isCheck
|
}
|
},
|
removeObj(arr){
|
console.log(arr,'arr2')
|
if(arr){
|
if(arr.length !== 0){
|
arr.forEach((i,index)=>{
|
if(i.child && i.child.length !== 0){
|
this.removeObj(i.child)
|
} else {
|
if(!i.isCheck){
|
arr.splice(index,1)
|
}
|
}
|
})
|
}
|
}
|
},
|
/** 保存 */
|
async save(){
|
if(this.controlName === ''){
|
this.$toast({
|
type:'warning',
|
message:'布控名称不能为空!'
|
})
|
return false
|
}
|
let Ids = []
|
const _getNodeId = data => {
|
let {obj,arr} = data
|
if(obj.type === '2'){
|
arr.push(obj.id)
|
}
|
if(obj.child && obj.child.length !== 0 ){
|
obj.child.forEach((item,index)=>{
|
_getNodeId({obj:item,arr:arr})
|
})
|
}
|
}
|
this.selectNode.forEach(item=>{
|
_getNodeId({obj:item,arr:Ids})
|
})
|
let json = {}
|
let isEdit = this.$route.query.isEdit
|
if(this.ctrolObj && this.ctrolObj.id && isEdit){
|
json = {
|
id:this.ctrolObj.id,
|
taskName:this.controlName,
|
threshold:this.thresholdNum,
|
startTime:this.controlTime[0],
|
endTime:this.controlTime[1],
|
nowDevIds:Ids
|
}
|
}else{
|
json = {
|
taskName:this.controlName,
|
threshold:this.thresholdNum,
|
startTime:this.controlTime[0],
|
endTime:this.controlTime[1],
|
Ids:Ids
|
}
|
}
|
console.log(json,'json save')
|
let res
|
if(isEdit){
|
res = await updateTask(json)
|
}else{
|
res = await addTask(json)
|
}
|
if(res && res.success){
|
this.$toast({
|
type:'success',
|
message:'保存成功!'
|
})
|
}else{
|
if(res.code === 40100){
|
this.$toast({
|
type:'warning',
|
message:'存在相同布控名称,请修改!'
|
})
|
}else{
|
this.$toast({
|
type:'error',
|
message:'保存失败!'
|
})
|
}
|
}
|
},
|
/** 取消 */
|
cancel(){},
|
/** 已勾选树的删除方法 */
|
delSelected(node){
|
let deviceId = []
|
this.getTreeId(node,deviceId)
|
this.$refs.treeall.removeCheck(deviceId,node)
|
},
|
/** 获取集群设备树 */
|
async getClusterDeviceTree(){
|
let res = await getClusterDeviceTree()
|
if(res && res.success){
|
if(res.data && res.data.length !== 0){
|
/** 设置没有子节点的节点不可勾选 */
|
const _setDisabled = data =>{
|
if(data.child && data.child !== null){
|
this.$set(data,'disabled',false)
|
this.$set(data,'isDevice',false)
|
this.$set(data,'isCheck',false)
|
data.child.forEach(i=>{
|
_setDisabled(i)
|
})
|
}else{
|
this.$set(data,'isCheck',true)
|
this.$set(data,'isDevice',true)
|
this.$set(data,'disabled',true)
|
}
|
}
|
res.data.forEach((item)=>{
|
_setDisabled(item)
|
})
|
this.treeDataAll = res.data
|
// console.log(this.treeDataAll,'this.treeDataAll getClusterDeviceTree')
|
this.$nextTick(()=>{
|
if(this.$route.query.rowData){
|
this.findOneTask(this.$route.query.rowData.id)
|
}
|
})
|
}
|
}else{
|
this.$toast({
|
type:'error',
|
message:'查询集群设备树信息失败!'
|
})
|
}
|
},
|
/** 根据任务ID查询信息 */
|
async findOneTask(id){
|
let res = await findOneTask({
|
taskId:id
|
})
|
if(res && res.success){
|
// console.log(this.treeDataAll,'this.treeDataAll findOneTask',res)
|
this.ctrolObj = res.data
|
this.controlName = this.ctrolObj.name
|
this.thresholdNum = this.ctrolObj.threshold
|
let start = this.ctrolObj.startTime
|
let endtime = this.ctrolObj.endTime
|
this.controlTime = [this.$moment(start).format('YYYY/MM/DD HH:mm:ss'),this.$moment(endtime).format('YYYY/MM/DD HH:mm:ss'),]
|
/** 将选择的设备树勾选 */
|
if(this.ctrolObj.devIds && this.ctrolObj.devIds.length !== 0){
|
this.ctrolObj.devIds.forEach(item=>{
|
let allNodes = []
|
this.treeDataAll.forEach(temp=>{
|
this.getTreeNode(temp,allNodes)
|
})
|
for(let i of allNodes){
|
if(i.id === item){
|
this.$set(i,'isCheck',false)
|
console.log(i,'findOneTask handleNodeClick')
|
this.$refs.treeall.handleNodeClick(i)
|
break
|
}
|
}
|
})
|
}
|
}
|
},
|
/** 停止布控 */
|
async stopTask(){
|
if(this.$route.query.isEdit){
|
if(this.ctrolObj && this.ctrolObj.id){
|
let res = await stopTask({id:this.ctrolObj.id})
|
if(res && res.success){
|
this.$toast({
|
type:'success',
|
message:'停止布控成功!'
|
})
|
}else{
|
this.$toast({
|
type:'error',
|
message:'停止布控失败!'
|
})
|
}
|
}
|
}
|
},
|
/** 删除布控 */
|
async delTask(){
|
if(this.$route.query.isEdit){
|
if(this.ctrolObj && this.ctrolObj.id){
|
let res = await delTask({id:this.ctrolObj.id})
|
if(res && res.success){
|
this.$toast({
|
type:'success',
|
message:'删除布控成功!'
|
})
|
}else{
|
this.$toast({
|
type:'error',
|
message:'删除布控失败!'
|
})
|
}
|
}
|
}
|
},
|
/** 筛选所选设备树节点中的设备,传给地图 */
|
getDevicesToMap(){
|
let devices = []
|
this.selectNode.forEach(item=>{
|
this.getTreeNode(item,devices)
|
})
|
devices = devices.filter((item)=>{
|
return item.isDevice
|
})
|
this.allDevices = devices
|
console.log(this.allDevices,'devices')
|
},
|
/** 地图上的选择某个设备 */
|
selectDevice(data){
|
if(data){
|
this.$refs.map.setActive(data)
|
}
|
}
|
},
|
mounted() {
|
this.getClusterDeviceTree()
|
},
|
watch: {
|
controlName: function (newVal, oldVal) {
|
// console.log(newVal, '监听任务名称')
|
},
|
checkAll:function (newVal,oldVal){
|
if(newVal){
|
let arr = []
|
this.treeDataAll.forEach((i,index)=>{
|
this.getTreeId(i,arr)
|
})
|
this.$refs.treeall.setCurrentKey(arr)
|
this.selectNode = this.treeDataAll
|
}else{
|
this.$refs.treeall.cancleCheck()
|
this.selectNode = []
|
}
|
},
|
selectNode:{
|
handler:function(newVal,oldVal){
|
if(newVal !== oldVal && newVal.length !== 0){
|
this.getDevicesToMap()
|
}
|
},
|
deep:true
|
}
|
}
|
}
|
</script>
|
<style lang="scss" scoped>
|
.out-div{
|
width: 100%;
|
height: 100%;
|
.left-div{
|
width: 25%;
|
height: 100%;
|
background-color: white;
|
font-size: 16px;
|
margin-right: 20px;
|
}
|
.right-div{
|
width: 75%;
|
height: 100%;
|
background-color: white;
|
margin-left: 20px;
|
.right-tree-all{
|
width: 50%;
|
height: 100%;
|
margin-right: 15px;
|
}
|
.select-node{
|
width: 50%;
|
height: 100%;
|
margin-left: 15px;
|
}
|
}
|
.data-time-pick{
|
position: relative;
|
width: 100%;
|
min-height: 1px;
|
padding-right: 0.75rem;
|
}
|
}
|
.table-switch-btn {
|
height: 40px;
|
line-height: 30px;
|
font-size: 30px;
|
padding: 5px 8px;
|
color: #ccc;
|
cursor: pointer;
|
&.active {
|
color: #35bde7;
|
}
|
}
|
.save-cancel{
|
position: absolute;
|
bottom: 20px;
|
width: 100%
|
}
|
.el-button--primary {
|
color: #fff;
|
background-color: #35bde7;
|
border-color: #35bde7;
|
}
|
.map-tree{
|
width: 100%;
|
height: 60vh;
|
.map{
|
margin-top: 30px;
|
height: 60vh;
|
}
|
}
|
</style>
|