Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
web-monitor
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
web-monitor
Commits
464317a4
Commit
464317a4
authored
Jan 27, 2022
by
yanzhongrong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
left tree bug
parent
02e88153
Pipeline
#442
failed with stages
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
642 additions
and
6 deletions
+642
-6
Tree.vue
src/components/Tree.vue
+265
-0
orgTree.vue
src/components/orgTree.vue
+182
-0
Navbar.vue
src/layout/components/Navbar.vue
+4
-3
tree.js
src/mixins/tree.js
+119
-0
index.js
src/router/index.js
+67
-1
index.vue
src/views/dashboard/index.vue
+5
-2
No files found.
src/components/Tree.vue
0 → 100644
View file @
464317a4
<
template
>
<div>
<el-tree
ref=
"elTree"
class=
"el-select-tree__list"
:default-expanded-keys=
"defaultExpandedKeys"
:show-checkbox=
"multiple"
:expand-on-click-node=
"multiple"
:style=
"
{ 'min-width': minWidth + 'px' }"
@node-click="nodeClick"
@check-change="checkChange"
:data="data"
:props="props"
:node-key="propsValue"
:default-expand-all="defaultExpandAll"
:check-strictly="checkStrictly"
:lazy="lazy"
:load="load"
:icon-class="iconClass"
:indent="indent"
:accordion="accordion"
:filter-node-method="filterNode"
:auto-expand-parent="autoExpandParent"
:render-content="renderContent"
:render-after-expand="renderAfterExpand"
>
<span
slot-scope=
"
{ data }"
class="el-select-tree__item"
:class="treeItemClass(data)"
>
<template
v-if=
"data.type === 1"
>
<svg-icon
icon-class=
"org"
/>
<span
class=
"ml10"
:title=
"data[propsLabel]"
>
{{
data
[
propsLabel
]
}}
</span>
</
template
>
<
template
v-else-if=
"data.type === 2"
>
<svg-icon
:icon-class=
"`car_$
{data.data.carstatus}`"
/>
<span
class=
"ml10"
:title=
"data[propsLabel]"
>
{{
data
[
propsLabel
]
}}
</span>
</
template
>
<
template
v-else-if=
"data.type === 3"
>
<svg-icon
icon-class=
"human"
/>
<span
class=
"ml10"
:title=
"data[propsLabel]"
>
{{
data
[
propsLabel
]
}}
</span>
</
template
>
<
template
v-else-if=
"hasChannel"
>
<svg-icon
icon-class=
"camera"
/>
<span
class=
"ml10"
:title=
"data[propsLabel]"
>
{{
data
[
propsLabel
]
}}
</span>
</
template
>
</span>
</el-tree>
</div>
</template>
<
script
>
import
Emitter
from
'element-ui/lib/mixins/emitter'
import
{
addResizeListener
,
removeResizeListener
}
from
'element-ui/lib/utils/resize-event'
export
default
{
name
:
'tree'
,
data
()
{
return
{
minWidth
:
0
}
},
mixins
:
[
Emitter
],
model
:
{
prop
:
'value'
,
event
:
'change'
},
props
:
{
data
:
{
type
:
Array
,
default
()
{
return
[]
}
},
props
:
{
type
:
Object
,
default
()
{
return
{
value
:
'value'
,
label
:
'label'
,
children
:
'children'
,
disabled
:
'disabled'
,
isLeaf
:
'isLeaf'
};
}
},
canFilter
:
Boolean
,
filterText
:
String
,
checkStrictly
:
Boolean
,
nodeKey
:
String
,
defaultExpandAll
:
Boolean
,
lazy
:
Boolean
,
load
:
Function
,
iconClass
:
String
,
indent
:
Number
,
accordion
:
Boolean
,
autoExpandParent
:
{
type
:
Boolean
,
default
:
true
},
renderContent
:
Function
,
renderAfterExpand
:
Boolean
,
// [el-tree] forwarding parameters end
multiple
:
Boolean
,
value
:
{
type
:
[
Number
,
String
,
Array
,
Object
],
default
:
''
},
},
computed
:
{
propsValue
()
{
return
this
.
nodeKey
||
this
.
props
.
value
||
'value'
},
propsLabel
()
{
return
this
.
props
.
label
||
'label'
},
propsIsLeaf
()
{
return
this
.
props
.
isLeaf
||
'isLeaf'
},
defaultExpandedKeys
()
{
return
Array
.
isArray
(
this
.
value
)
?
this
.
value
:
this
.
value
||
this
.
value
===
0
?
[
this
.
value
]
:
[]
}
},
watch
:
{
value
:
{
immediate
:
true
,
handler
(
val
)
{
if
(
val
.
length
>
0
)
{
this
.
setSelected
()
}
}
},
data
:
{
immediate
:
true
,
handler
(
val
)
{
if
(
val
.
length
>
0
)
{
this
.
setSelected
()
}
}
},
filterText
:
{
immediate
:
true
,
handler
(
val
)
{
if
(
this
.
canFilter
&&
this
.
$refs
.
elTree
)
{
this
.
$refs
.
elTree
.
filter
(
val
)
}
}
}
},
methods
:
{
filterNode
(
value
,
data
,
node
)
{
if
(
!
value
){
return
true
}
if
(
data
.
label
.
indexOf
(
value
)
!==-
1
)
{
return
true
}
return
this
.
checkBelongToChooseNode
(
value
,
data
,
node
)
},
checkBelongToChooseNode
(
value
,
data
,
node
)
{
const
level
=
node
.
level
let
parentData
=
node
.
parent
let
index
=
0
while
(
index
<
level
-
1
)
{
if
(
parentData
.
data
.
label
.
indexOf
(
value
)
!==-
1
)
{
return
true
}
parentData
=
parentData
.
parent
index
++
}
return
false
},
valueChange
(
value
,
node
)
{
this
.
$emit
(
'change'
,
value
,
node
)
},
clear
()
{
if
(
this
.
multiple
)
{
this
.
valueChange
([])
this
.
$nextTick
(()
=>
{
this
.
$refs
.
elTree
.
setCheckedKeys
([])
})
}
else
{
this
.
valueChange
(
''
)
}
this
.
$emit
(
'clear'
)
},
nodeClick
(
data
,
_
,
component
)
{
const
children
=
data
[
this
.
props
.
children
]
const
value
=
data
[
this
.
propsValue
]
if
(
((
children
&&
children
.
length
)
||
(
this
.
lazy
&&
!
data
[
this
.
propsIsLeaf
]))
&&
!
this
.
checkStrictly
)
{
component
.
handleExpandIconClick
()
}
else
if
(
!
this
.
multiple
&&
!
data
.
disabled
)
{
if
(
value
!==
this
.
value
)
{
this
.
valueChange
(
value
,
data
)
}
}
},
checkChange
()
{
const
elTree
=
this
.
$refs
.
elTree
const
leafOnly
=
!
this
.
checkStrictly
const
keys
=
elTree
.
getCheckedKeys
(
leafOnly
)
const
nodes
=
elTree
.
getCheckedNodes
(
leafOnly
)
this
.
valueChange
(
keys
,
nodes
)
},
setSelected
()
{
this
.
$nextTick
(()
=>
{
const
elTree
=
this
.
$refs
.
elTree
if
(
!
elTree
)
return
if
(
this
.
multiple
)
{
elTree
.
setCheckedKeys
(
this
.
value
)
this
.
checkChange
()
}
else
{
const
selectedNode
=
elTree
.
getNode
(
this
.
value
)
this
.
valueChange
(
this
.
value
,
selectedNode
)
}
})
},
treeItemClass
(
data
)
{
return
{
'is-selected'
:
this
.
multiple
?
false
:
data
[
this
.
propsValue
]
===
this
.
value
,
'is-disabled'
:
data
.
disabled
}
},
handleResize
()
{
// set the `tree` default `min-width`
// border's width is 2px
this
.
minWidth
=
this
.
$el
.
clientWidth
-
2
}
},
mounted
()
{
this
.
setSelected
()
addResizeListener
(
this
.
$el
,
this
.
handleResize
)
},
beforeDestroy
()
{
if
(
this
.
$el
&&
this
.
handleResize
)
{
removeResizeListener
(
this
.
$el
,
this
.
handleResize
)
}
}
}
</
script
>
\ No newline at end of file
src/components/orgTree.vue
0 → 100644
View file @
464317a4
<
template
>
<div
class=
"el-select-tree"
>
<el-popover
ref=
"elPopover"
v-model=
"visible"
transition=
"el-zoom-in-top"
popper-class=
"el-select-tree__popover"
trigger=
"click"
:disabled=
"disabled"
:placement=
"placement"
:width=
"popoverWidth"
@
after-enter=
"handleScroll()"
>
<div
class=
"card-board"
>
<el-input
v-model=
"keyword"
:placeholder=
"searchPlaceholder"
:size=
"size"
clearable
>
</el-input>
<!-- scrollbar wrap -->
<el-scrollbar
wrap-class=
"el-select-dropdown__wrap"
view-class=
"el-select-dropdown__list"
ref=
"scrollbar"
>
<tree
ref=
"tree"
v-model=
"valueInner"
@
change=
"change"
:canFilter=
"canFilter"
:filterText=
"keyword"
:checkStrictly=
"checkStrictly"
:defaultExpandAll=
true
:data=
"treeData"
>
</tree>
</el-scrollbar>
</div>
<!-- trigger input -->
<el-input
v-model=
"selectedLabel"
ref=
"reference"
slot=
"reference"
readonly
:style=
"selectStyle"
:validate-event=
"false"
:size=
"size"
:class=
"
{
'is-active': visible,
'is-selected': selectedLabel,
'is-clearable': clearable
}"
:disabled="disabled"
:placeholder="placeholder"
>
<i
v-if=
"clearable"
@
click
.
stop=
"clear()"
slot=
"suffix"
class=
"el-input__icon el-input__icon-close el-icon-circle-close"
></i>
<i
slot=
"suffix"
class=
"el-input__icon el-input__icon-arrow-down el-icon-arrow-down"
></i>
</el-input>
</el-popover>
</div>
</
template
>
<
script
>
import
{
TreeMixin
,
}
from
'@/mixins/tree'
import
{
mapGetters
}
from
'vuex'
export
default
{
data
()
{
return
{
canFilter
:
true
}
},
name
:
'org-tree'
,
mixins
:
[
TreeMixin
],
computed
:
{
...
mapGetters
(
'tree'
,
[
'treeData'
,
])
},
}
</
script
>
<
style
lang=
"scss"
>
@import
'@/styles/variables'
;
.el-select-tree
{
border
:
1px
dotted
;
display
:
inline-block
;
.el-input__icon
{
cursor
:
pointer
;
transition
:
transform
0
.3s
;
&
-close
{
display
:
none
;
}
}
.el-input__inner
{
cursor
:
pointer
;
padding-right
:
30px
;
}
.el-input
{
&
:hover:not
(
.is-disabled
)
{
.el-input__inner
{
// border-color: $--input-border-color-hover;
}
&
.is-selected.is-clearable
{
.el-input__icon
{
&
-close
{
display
:
inline-block
;
}
&
-arrow-down
{
display
:
none
;
}
}
}
}
&
.is-active
{
.el-input__icon-arrow-down
{
transform
:
rotate
(
-180deg
);
}
.el-input__inner
{
// border-color: $--button-primary-border-color;
}
}
}
&
__popover
{
padding
:
0
!
important
;
// extends el-select-dropdown - start
// border: $--select-dropdown-border !important;
// border-radius: $--border-radius-base !important;
// extends el-select-dropdown - end
.popper__arrow
{
left
:
35px
!
important
;
}
.el-tree-node__expand-icon.is-leaf
{
cursor
:
pointer
;
}
}
&
__list
{
overflow-y
:
auto
;
// scroll style - start
&
:
:-
webkit-scrollbar-track-piece
{
background
:
#d3dce6
;
}
&
:
:-
webkit-scrollbar
{
width
:
4px
;
}
&
:
:-
webkit-scrollbar-thumb
{
background
:
#99a9bf
;
}
// scroll style - end
}
&
__item
{
position
:
relative
;
white-space
:
nowrap
;
// padding-right: $spacing-medium;
&
.is-selected
{
// color: $--select-option-selected-font-color;
font-weight
:
bolder
;
}
&
.is-disabled
{
// color: $--font-color-disabled-base;
cursor
:
not
-
allowed
;
}
}
}
</
style
>
\ No newline at end of file
src/layout/components/Navbar.vue
View file @
464317a4
...
...
@@ -3,7 +3,6 @@
<!--
<hamburger
:is-active=
"sidebar.opened"
class=
"hamburger-container"
@
toggleClick=
"toggleSideBar"
/>
-->
<!--
<breadcrumb
class=
"breadcrumb-container"
/>
-->
<div
class=
"log"
>
后台管理系统
</div>
<Sidebar
/>
<div
class=
"right-menu"
>
<el-dropdown
class=
"avatar-container"
trigger=
"click"
>
...
...
@@ -57,13 +56,12 @@ export default {
<
style
lang=
"scss"
scoped
>
.navbar
{
height
:
80px
;
overflow
:
hidden
;
position
:
relative
;
background
:
#fff
;
box-shadow
:
0
1px
4px
rgba
(
0
,
21
,
41
,.
08
);
.log
{
font-size
:
2
0
px
;
font-size
:
2
4
px
;
color
:
#fff
;
float
:
left
;
}
...
...
@@ -88,6 +86,9 @@ export default {
float
:
right
;
height
:
100%
;
line-height
:
50px
;
position
:
absolute
;
top
:
5px
;
right
:
20px
;
&
:focus
{
outline
:
none
;
...
...
src/mixins/tree.js
0 → 100644
View file @
464317a4
import
Tree
from
"@/components/Tree"
;
export
const
TreeMixin
=
{
model
:
{
prop
:
"value"
,
event
:
"change"
,
},
props
:
{
clearable
:
Boolean
,
selectWidth
:
Number
,
popoverWidth
:
Number
,
placement
:
{
type
:
String
,
default
:
"bottom-start"
,
},
disabled
:
Boolean
,
placeholder
:
{
type
:
String
,
default
:
"请选择"
,
},
searchPlaceholder
:
{
type
:
String
,
default
:
"请输入"
,
},
size
:
{
type
:
String
,
default
:
"small"
,
},
multiple
:
{
type
:
Boolean
,
default
:
false
},
value
:
{
type
:
[
Number
,
String
,
Array
,
Object
],
default
:
""
,
},
},
data
()
{
return
{
visible
:
false
,
checkStrictly
:
true
,
selectedNode
:
null
,
keyword
:
""
,
};
},
components
:
{
Tree
,
},
watch
:
{
value
(
newV
)
{
if
(
!
newV
)
{
this
.
selectedNode
=
null
}
}
},
mounted
()
{
this
.
init
&&
this
.
init
();
},
computed
:
{
valueInner
:
{
get
()
{
return
this
.
value
;
},
set
(
val
)
{
this
.
$emit
(
"change"
,
val
);
},
},
selectedLabel
()
{
if
(
!
this
.
selectedNode
)
return
""
;
return
this
.
selectedNode
.
label
;
},
selectStyle
()
{
if
(
this
.
selectWidth
)
{
return
{
width
:
this
.
selectWidth
+
"px"
,
};
}
},
},
methods
:
{
change
(
value
,
data
)
{
if
(
!
value
.
leaf
&&
this
.
ignoreParentChoose
)
return
;
if
(
data
)
{
this
.
selectedNode
=
data
;
}
this
.
$emit
(
"change"
,
value
,
data
);
if
(
!
this
.
multiple
)
{
this
.
visible
=
false
;
}
},
valueChange
(
value
,
node
)
{
this
.
$emit
(
"change"
,
value
,
node
);
},
clear
()
{
if
(
this
.
multiple
)
{
this
.
valueChange
([]);
}
else
{
this
.
visible
=
false
;
this
.
valueChange
(
""
);
this
.
selectedNode
=
null
;
}
},
// 触发滚动条的重置
handleScroll
()
{
this
.
$refs
.
scrollbar
&&
this
.
$refs
.
scrollbar
.
handleScroll
();
},
},
};
export
function
travelTree
(
treeData
,
idKey
,
labelKey
)
{
let
len
=
treeData
.
length
;
for
(
let
i
=
0
;
i
<
len
;
i
++
)
{
let
curData
=
treeData
[
i
];
if
(
curData
.
children
&&
curData
.
children
.
length
)
{
curData
.
label
=
`
${
curData
.
data
[
labelKey
]}
(
${
curData
.
children
.
length
}
)`
;
travelTree
(
curData
.
children
,
idKey
,
labelKey
);
}
else
{
curData
.
label
=
curData
.
data
[
labelKey
];
}
curData
.
value
=
curData
.
data
[
idKey
];
}
}
src/router/index.js
View file @
464317a4
...
...
@@ -51,7 +51,73 @@ export const constantRoutes = [
path
:
'dashboard'
,
name
:
'Dashboard'
,
component
:
()
=>
import
(
'@/views/dashboard/index'
),
meta
:
{
title
:
'Dashboard'
,
icon
:
'dashboard'
}
meta
:
{
title
:
'首页'
,
icon
:
'dashboard'
}
}]
},
{
path
:
'/alarm'
,
component
:
Layout
,
redirect
:
'/dashboard'
,
children
:
[{
path
:
'alarm'
,
name
:
'Alarm'
,
component
:
()
=>
import
(
'@/views/dashboard/index'
),
meta
:
{
title
:
'告警管理'
,
icon
:
'dashboard'
}
}]
},
{
path
:
'/setting'
,
component
:
Layout
,
redirect
:
'/dashboard'
,
children
:
[{
path
:
'setting'
,
name
:
'Setting'
,
component
:
()
=>
import
(
'@/views/dashboard/index'
),
meta
:
{
title
:
'配置管理'
,
icon
:
'dashboard'
}
}]
},
{
path
:
'/monitor'
,
component
:
Layout
,
redirect
:
'/dashboard'
,
children
:
[{
path
:
'monitor'
,
name
:
'Monitor'
,
component
:
()
=>
import
(
'@/views/dashboard/index'
),
meta
:
{
title
:
'监测实时状态'
,
icon
:
'dashboard'
}
}]
},
{
path
:
'/maintain'
,
component
:
Layout
,
redirect
:
'/dashboard'
,
children
:
[{
path
:
'maintain'
,
name
:
'Maintain'
,
component
:
()
=>
import
(
'@/views/dashboard/index'
),
meta
:
{
title
:
'维护管理'
,
icon
:
'dashboard'
}
}]
},
{
path
:
'/history'
,
component
:
Layout
,
redirect
:
'/dashboard'
,
children
:
[{
path
:
'history'
,
name
:
'History'
,
component
:
()
=>
import
(
'@/views/dashboard/index'
),
meta
:
{
title
:
'历史数据'
,
icon
:
'dashboard'
}
}]
},
{
path
:
'/user'
,
component
:
Layout
,
redirect
:
'/dashboard'
,
children
:
[{
path
:
'user'
,
name
:
'User'
,
component
:
()
=>
import
(
'@/views/dashboard/index'
),
meta
:
{
title
:
'用户管理'
,
icon
:
'dashboard'
}
}]
},
...
...
src/views/dashboard/index.vue
View file @
464317a4
<
template
>
<div
class=
"dashboard-container"
>
<
div
class=
"dashboard-text"
>
name:
{{
name
}}
</div
>
<
OrgTree
/
>
</div>
</
template
>
<
script
>
import
{
mapGetters
}
from
'vuex'
import
OrgTree
from
'@/components/orgTree.vue'
export
default
{
name
:
'Dashboard'
,
components
:
{
OrgTree
},
computed
:
{
...
mapGetters
([
'name'
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment