Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
DC-TOM
Project
Project
Details
Activity
Releases
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
刘照晖
DC-TOM
Commits
61b61fd1
Commit
61b61fd1
authored
May 20, 2025
by
Cai Wei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(*): 首页及除尘器总览页
parent
67b4d439
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
778 additions
and
161 deletions
+778
-161
close.png
src/assets/icons/close.png
+0
-0
health.png
src/assets/icons/health.png
+0
-0
warn.png
src/assets/icons/warn.png
+0
-0
index.js
src/router/index.js
+3
-2
chart-line.vue
src/views/dashboard/components/chart-line.vue
+5
-6
map-svg.vue
src/views/dashboard/components/map-svg.vue
+351
-0
msg-item.vue
src/views/dashboard/components/msg-item.vue
+157
-141
index.vue
src/views/dashboard/index.vue
+9
-12
index.vue
src/views/dustOverview/index.vue
+253
-0
No files found.
src/assets/icons/close.png
0 → 100644
View file @
61b61fd1
2.35 KB
src/assets/icons/health.png
0 → 100644
View file @
61b61fd1
2.04 KB
src/assets/icons/warn.png
0 → 100644
View file @
61b61fd1
2.33 KB
src/router/index.js
View file @
61b61fd1
import
{
createWebHistory
,
createRouter
}
from
'vue-router'
import
{
createWebHistory
,
createRouter
}
from
'vue-router'
import
Dashboard
from
'../views/dashboard/index.vue'
import
Dashboard
from
'../views/dashboard/index.vue'
import
DustOverview
from
'../views/dustOverview/index.vue'
import
HomeView
from
'../views/HomeView.vue'
import
HomeView
from
'../views/HomeView.vue'
import
AboutView
from
'../views/AboutView.vue'
import
AboutView
from
'../views/AboutView.vue'
import
User
from
'../views/user.vue'
import
User
from
'../views/user.vue'
...
@@ -18,8 +19,8 @@ const routes = [
...
@@ -18,8 +19,8 @@ const routes = [
meta
:
{
title
:
'首页'
},
meta
:
{
title
:
'首页'
},
},
},
{
{
path
:
'/overview'
,
path
:
'/
dust-
overview'
,
component
:
HomeV
iew
,
component
:
DustOverv
iew
,
meta
:
{
title
:
'除尘器总览'
},
meta
:
{
title
:
'除尘器总览'
},
},
},
{
{
...
...
src/views/dashboard/components/chart-line.vue
View file @
61b61fd1
...
@@ -3,9 +3,9 @@
...
@@ -3,9 +3,9 @@
</
template
>
</
template
>
<
script
setup
>
<
script
setup
>
import
{
onMounted
,
onBeforeUnmount
,
ref
}
from
'vue'
;
import
{
onMounted
,
onBeforeUnmount
,
ref
}
from
"vue"
;
import
*
as
echarts
from
'echarts'
;
import
*
as
echarts
from
"echarts"
;
import
{
getLineOption
}
from
'@/utils/chart'
;
import
{
getLineOption
}
from
"@/utils/chart"
;
const
chartRef
=
ref
(
null
);
const
chartRef
=
ref
(
null
);
let
chartInstance
=
null
;
let
chartInstance
=
null
;
...
@@ -13,7 +13,7 @@ let chartInstance = null;
...
@@ -13,7 +13,7 @@ let chartInstance = null;
const
initChart
=
()
=>
{
const
initChart
=
()
=>
{
if
(
chartRef
.
value
)
{
if
(
chartRef
.
value
)
{
chartInstance
=
echarts
.
init
(
chartRef
.
value
);
chartInstance
=
echarts
.
init
(
chartRef
.
value
);
const
xData
=
[
'01'
,
'02'
,
'03'
,
'04'
,
'05'
,
'06'
,
'07'
];
const
xData
=
[
"01"
,
"02"
,
"03"
,
"04"
,
"05"
,
"06"
,
"07"
];
const
seriesData
=
[
120
,
200
,
150
,
80
,
60
,
110
,
120
];
const
seriesData
=
[
120
,
200
,
150
,
80
,
60
,
110
,
120
];
const
option
=
getLineOption
(
xData
,
seriesData
);
const
option
=
getLineOption
(
xData
,
seriesData
);
chartInstance
.
setOption
(
option
);
chartInstance
.
setOption
(
option
);
...
@@ -22,7 +22,7 @@ const initChart = () => {
...
@@ -22,7 +22,7 @@ const initChart = () => {
onMounted
(()
=>
{
onMounted
(()
=>
{
initChart
();
initChart
();
window
.
addEventListener
(
'resize'
,
()
=>
{
window
.
addEventListener
(
"resize"
,
()
=>
{
chartInstance
?.
resize
();
chartInstance
?.
resize
();
});
});
});
});
...
@@ -38,4 +38,3 @@ onBeforeUnmount(() => {
...
@@ -38,4 +38,3 @@ onBeforeUnmount(() => {
height
:
calc
(
100%
-
22px
);
height
:
calc
(
100%
-
22px
);
}
}
</
style
>
</
style
>
\ No newline at end of file
src/views/dashboard/components/map-svg.vue
0 → 100644
View file @
61b61fd1
<
template
>
<div
class=
"svg-box"
>
<div
class=
"svg-main"
>
<img
src=
"@/assets/map.png"
alt=
""
/>
<div
class=
"spot-box"
>
<div
v-for=
"(spot, index) in spots"
:key=
"index"
class=
"spot"
:class=
"[
{ active: activeSpot === index }, `status-${spot.status}`]"
@mouseenter="handleSpotHover(index)"
@mouseleave="handleSpotLeave"
:style="{
left: spot.x + '%',
top: spot.y + '%',
}"
>
<div
class=
"pulse"
></div>
<!-- 连接线和详情窗 -->
<transition
name=
"line"
>
<div
class=
"connector-line"
v-if=
"activeSpot === index"
></div>
</transition>
<transition
name=
"detail"
@
before-enter=
"beforeEnter"
@
enter=
"enter"
@
leave=
"leave"
>
<div
class=
"detail-window"
v-if=
"activeSpot === index && showDetail"
>
<div
class=
"detail-title"
>
{{
spot
.
title
}}
</div>
<div
class=
"detail-content"
>
<div
class=
"detail-item"
>
<span
class=
"label"
>
状态:
</span>
<span
class=
"value"
:class=
"`text-status-$
{spot.status}`">
{{
getStatusText
(
spot
.
status
)
}}
</span>
</div>
<!--
<div
class=
"detail-item"
>
<span
class=
"label"
>
数值:
</span>
<span
class=
"value"
>
{{
spot
.
value
}}
</span>
</div>
-->
<div
class=
"detail-item"
>
<span
class=
"label"
>
描述:
</span>
<span
class=
"value"
>
{{
spot
.
description
}}
</span>
</div>
</div>
</div>
</transition>
</div>
</div>
</div>
</div>
</
template
>
<
script
setup
>
import
{
onMounted
,
onBeforeUnmount
,
ref
}
from
"vue"
;
import
*
as
echarts
from
"echarts"
;
import
{
getLineOption
}
from
"@/utils/chart"
;
// 定义坐标点位数据
const
spots
=
ref
([
{
x
:
41
,
y
:
22
,
title
:
"4#除尘器"
,
value
:
"89%"
,
status
:
"normal"
,
description
:
"无异常"
,
},
{
x
:
45
,
y
:
70
,
title
:
"站点B"
,
value
:
"92%"
,
status
:
"normal"
,
description
:
"运行正常"
,
},
{
x
:
65
,
y
:
36
,
title
:
"3#除尘器"
,
value
:
"78%"
,
status
:
"warning"
,
description
:
"三仓室存在轻微泄漏"
,
},
{
x
:
60
,
y
:
70
,
title
:
"2#除尘器"
,
value
:
"45%"
,
status
:
"error"
,
description
:
"除尘器脉冲阀故障或者提升阀故障"
,
},
]);
const
activeSpot
=
ref
(
null
);
const
showDetail
=
ref
(
false
);
const
hoverTimer
=
ref
(
null
);
const
clearTimer
=
()
=>
{
if
(
hoverTimer
.
value
)
{
clearTimeout
(
hoverTimer
.
value
);
hoverTimer
.
value
=
null
;
}
};
const
handleSpotHover
=
(
index
)
=>
{
clearTimer
();
activeSpot
.
value
=
index
;
hoverTimer
.
value
=
setTimeout
(()
=>
{
showDetail
.
value
=
true
;
hoverTimer
.
value
=
null
;
},
300
);
};
const
handleSpotLeave
=
()
=>
{
clearTimer
();
showDetail
.
value
=
false
;
hoverTimer
.
value
=
setTimeout
(()
=>
{
activeSpot
.
value
=
null
;
hoverTimer
.
value
=
null
;
},
300
);
};
// 详情窗动画钩子
const
beforeEnter
=
(
el
)
=>
{
el
.
style
.
opacity
=
0
;
el
.
style
.
transform
=
"translateX(-20px)"
;
};
const
enter
=
(
el
,
done
)
=>
{
el
.
style
.
transition
=
"all 0.3s ease-out"
;
setTimeout
(()
=>
{
el
.
style
.
opacity
=
1
;
el
.
style
.
transform
=
"translateX(0)"
;
},
0
);
};
const
leave
=
(
el
)
=>
{
el
.
style
.
transition
=
"all 0.3s ease-in"
;
el
.
style
.
opacity
=
0
;
el
.
style
.
transform
=
"translateX(-20px)"
;
};
const
getStatusText
=
(
status
)
=>
{
const
statusMap
=
{
normal
:
"正常"
,
warning
:
"警告"
,
error
:
"异常"
,
};
return
statusMap
[
status
]
||
status
;
};
onMounted
(()
=>
{});
onBeforeUnmount
(()
=>
{
clearTimer
();
});
</
script
>
<
style
scoped
lang=
"scss"
>
.svg-box
{
position
:
relative
;
width
:
100%
;
height
:
100%
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
.svg-main
{
position
:
relative
;
display
:
inline-block
;
height
:
100%
;
}
img
{
display
:
block
;
width
:
auto
;
height
:
100%
;
}
}
.spot-box
{
position
:
absolute
;
top
:
0
;
left
:
0
;
width
:
100%
;
height
:
100%
;
pointer-events
:
none
;
}
.spot
{
position
:
absolute
;
width
:
15px
;
height
:
15px
;
background
:
rgb
(
253
,
48
,
2
);
border-radius
:
50%
;
transform
:
translate
(
-50%
,
-50%
);
pointer-events
:
auto
;
cursor
:
pointer
;
z-index
:
2
;
// 状态颜色
&
.status-normal
{
background
:
#08c733
;
.pulse
{
background
:
#08c733
;
}
&
.active
.pulse
{
background
:
#08c733
;
}
}
&
.status-warning
{
background
:
#f5c701
;
.pulse
{
background
:
#f5c701
;
}
&
.active
.pulse
{
background
:
#f5c701
;
}
}
&
.status-error
{
background
:
#ff6a6a
;
.pulse
{
background
:
#ff6a6a
;
}
&
.active
.pulse
{
background
:
#ff6a6a
;
}
}
&
.active
{
box-shadow
:
0
0
10px
rgba
(
255
,
255
,
255
,
0
.5
);
}
.pulse
{
position
:
absolute
;
width
:
100%
;
height
:
100%
;
background
:
rgb
(
253
,
48
,
2
);
border-radius
:
50%
;
animation
:
pulse
1
.5s
ease-out
infinite
;
}
.connector-line
{
position
:
absolute
;
top
:
50%
;
left
:
50%
;
width
:
60px
;
// 缩短连接线长度
height
:
2px
;
background
:
linear-gradient
(
90deg
,
currentColor
,
rgba
(
89
,
93
,
89
,
0
.4
));
transform-origin
:
left
center
;
transform
:
rotate
(
-45deg
);
z-index
:
-1
;
}
// 连接线动画
.line-enter-active
{
transition
:
all
0
.3s
ease-out
;
transform-origin
:
left
center
;
}
.line-leave-active
{
transition
:
all
0
.3s
ease-in
;
transform-origin
:
left
center
;
}
.line-enter-from
,
.line-leave-to
{
opacity
:
0
;
width
:
0
;
}
.detail-window
{
position
:
absolute
;
left
:
calc
(
100%
+
35px
);
// 减小与连接线的距离
top
:
-40px
;
// 调整垂直位置
width
:
200px
;
background
:
rgba
(
0
,
22
,
40
,
0
.5
);
backdrop-filter
:
blur
(
8px
);
border
:
1px
solid
rgba
(
255
,
255
,
255
,
0
.3
);
border-radius
:
8px
;
padding
:
12px
;
color
:
#fff
;
pointer-events
:
none
;
z-index
:
3
;
.text-status-normal
{
color
:
#00ff9d
!
important
;
}
.text-status-warning
{
color
:
#ffa500
!
important
;
}
.text-status-error
{
color
:
#ff3b3b
!
important
;
}
&
:
:
before
{
content
:
""
;
position
:
absolute
;
left
:
-6px
;
top
:
50%
;
transform
:
translateY
(
-50%
);
width
:
0
;
height
:
0
;
border-top
:
6px
solid
transparent
;
border-bottom
:
6px
solid
transparent
;
border-right
:
6px
solid
rgba
(
255
,
255
,
255
,
0
.3
);
}
.detail-title
{
font-size
:
16px
;
font-weight
:
bold
;
color
:
#fff
;
// color: #00ff9d;
margin-bottom
:
8px
;
}
.detail-content
{
font-size
:
14px
;
.detail-item
{
display
:
flex
;
margin-bottom
:
4px
;
.label
{
width
:
50px
;
color
:
rgba
(
255
,
255
,
255
,
0
.7
);
}
.value
{
width
:
calc
(
100%
-
55px
);
color
:
#fff
;
}
}
}
}
}
@keyframes
pulse
{
0
%
{
transform
:
scale
(
1
);
opacity
:
1
;
}
100
%
{
transform
:
scale
(
3
);
opacity
:
0
;
}
}
</
style
>
src/views/dashboard/components/msg-item.vue
View file @
61b61fd1
<
template
>
<
template
>
<div
class=
"message-list"
@
mouseenter=
"pauseScroll"
@
mouseleave=
"resumeScroll"
>
<div
<div
class=
"message-wrapper"
ref=
"messageWrapper"
>
class=
"message-list"
<div
@
mouseenter=
"pauseScroll"
class=
"message-item"
@
mouseleave=
"resumeScroll"
v-for=
"(message, index) in extendedList"
>
:key=
"index"
<div
class=
"message-wrapper"
ref=
"messageWrapper"
>
>
<div
<span
class=
"time"
>
{{
message
.
time
}}
</span>
class=
"message-item"
<div
class=
"content"
><span
class=
"title"
>
{{
message
.
title
}}
</span>
{{
message
.
content
}}
</div>
v-for=
"(message, index) in extendedList"
:key=
"index"
>
<span
class=
"time"
>
{{
message
.
time
}}
</span>
<div
class=
"content"
>
<span
class=
"title"
>
{{
message
.
title
}}
</span
>
{{
message
.
content
}}
</div>
</div>
</div>
</div>
</div>
</div>
</
template
>
</div>
</
template
>
<
script
setup
>
import
{
ref
,
onMounted
,
onBeforeUnmount
,
nextTick
,
watch
}
from
'vue'
;
<
script
setup
>
import
{
ref
,
onMounted
,
onBeforeUnmount
,
nextTick
,
watch
}
from
"vue"
;
const
props
=
defineProps
({
msgList
:
{
const
props
=
defineProps
({
type
:
Array
,
msgList
:
{
default
:
()
=>
[]
type
:
Array
,
}
default
:
()
=>
[],
});
},
});
const
extendedList
=
ref
([]);
const
messageWrapper
=
ref
(
null
);
const
extendedList
=
ref
([]);
const
itemHeight
=
34
;
// 一条消息高度
const
messageWrapper
=
ref
(
null
);
const
scrollInterval
=
3000
;
// 每 2 秒滚动一次
const
itemHeight
=
34
;
// 一条消息高度
let
timer
=
null
;
const
scrollInterval
=
3000
;
// 每 2 秒滚动一次
let
isPaused
=
false
;
let
timer
=
null
;
let
isPaused
=
false
;
// 滚动逻辑:每 2 秒滚动一条(50px)
const
startScroll
=
()
=>
{
// 滚动逻辑:每 2 秒滚动一条(50px)
stopScroll
();
const
startScroll
=
()
=>
{
const
wrapper
=
messageWrapper
.
value
;
stopScroll
();
if
(
!
wrapper
)
return
;
const
wrapper
=
messageWrapper
.
value
;
if
(
!
wrapper
)
return
;
timer
=
setInterval
(()
=>
{
if
(
isPaused
)
return
;
timer
=
setInterval
(()
=>
{
if
(
isPaused
)
return
;
const
currentTop
=
parseInt
(
wrapper
.
style
.
transform
.
replace
(
'translateY('
,
''
).
replace
(
'px)'
,
''
))
||
0
;
const
nextTop
=
currentTop
-
itemHeight
;
const
currentTop
=
parseInt
(
wrapper
.
style
.
transition
=
'transform 0.5s'
;
wrapper
.
style
.
transform
.
replace
(
"translateY("
,
""
).
replace
(
"px)"
,
""
)
wrapper
.
style
.
transform
=
`translateY(
${
nextTop
}
px)`
;
)
||
0
;
const
nextTop
=
currentTop
-
itemHeight
;
const
listHeight
=
(
extendedList
.
value
.
length
/
2
)
*
itemHeight
;
if
(
Math
.
abs
(
nextTop
)
>=
listHeight
)
{
wrapper
.
style
.
transition
=
"transform 0.5s"
;
// 到底了,重置
wrapper
.
style
.
transform
=
`translateY(
${
nextTop
}
px)`
;
setTimeout
(()
=>
{
wrapper
.
style
.
transition
=
'none'
;
const
listHeight
=
(
extendedList
.
value
.
length
/
2
)
*
itemHeight
;
wrapper
.
style
.
transform
=
'translateY(0)'
;
if
(
Math
.
abs
(
nextTop
)
>=
listHeight
)
{
},
500
);
// 等待动画完成后重置
// 到底了,重置
}
setTimeout
(()
=>
{
},
scrollInterval
);
wrapper
.
style
.
transition
=
"none"
;
};
wrapper
.
style
.
transform
=
"translateY(0)"
;
},
500
);
// 等待动画完成后重置
const
stopScroll
=
()
=>
{
if
(
timer
)
{
clearInterval
(
timer
);
timer
=
null
;
}
};
const
pauseScroll
=
()
=>
{
isPaused
=
true
;
};
const
resumeScroll
=
()
=>
{
isPaused
=
false
;
};
// 数据更新时刷新滚动状态
const
updateScroll
=
()
=>
{
stopScroll
();
if
(
props
.
msgList
.
length
<
5
)
{
extendedList
.
value
=
[...
props
.
msgList
];
nextTick
(()
=>
{
if
(
messageWrapper
.
value
)
{
messageWrapper
.
value
.
style
.
transform
=
'translateY(0)'
;
messageWrapper
.
value
.
style
.
transition
=
'none'
;
}
});
}
else
{
extendedList
.
value
=
[...
props
.
msgList
,
...
props
.
msgList
];
// 实现无缝滚动
nextTick
(()
=>
{
if
(
messageWrapper
.
value
)
{
messageWrapper
.
value
.
style
.
transform
=
'translateY(0)'
;
messageWrapper
.
value
.
style
.
transition
=
'none'
;
}
startScroll
();
});
}
}
};
},
scrollInterval
);
};
// 生命周期钩子
onMounted
(()
=>
{
updateScroll
();
});
onBeforeUnmount
(()
=>
{
stopScroll
();
});
watch
(()
=>
props
.
msgList
,
()
=>
{
updateScroll
();
},
{
deep
:
true
});
</
script
>
<
style
scoped
>
.message-list
{
position
:
relative
;
overflow
:
hidden
;
max-height
:
160px
;
/* 7条 * 50px */
width
:
100%
;
height
:
calc
(
100%
-
22px
);
}
.message-wrapper
{
width
:
100%
;
}
.message-item
{
display
:
flex
;
align-items
:
center
;
font-size
:
14px
;
height
:
32px
;
line-height
:
32px
;
padding
:
1px
0
;
max-width
:
100%
;
const
stopScroll
=
()
=>
{
if
(
timer
)
{
clearInterval
(
timer
);
timer
=
null
;
}
}
.message-item
.time
{
};
color
:
#58616b
;
margin-right
:
5px
;
const
pauseScroll
=
()
=>
{
min-width
:
80px
;
isPaused
=
true
;
flex-shrink
:
0
;
};
}
const
resumeScroll
=
()
=>
{
.message-item
.title
{
isPaused
=
false
;
margin-right
:
5px
;
};
color
:
#0c0b0b
;
font-weight
:
bold
;
// 数据更新时刷新滚动状态
}
const
updateScroll
=
()
=>
{
.message-item
.content
{
stopScroll
();
flex
:
1
;
if
(
props
.
msgList
.
length
<
5
)
{
color
:
#58616b
;
extendedList
.
value
=
[...
props
.
msgList
];
overflow
:
hidden
;
nextTick
(()
=>
{
text-overflow
:
ellipsis
;
if
(
messageWrapper
.
value
)
{
white-space
:
nowrap
;
messageWrapper
.
value
.
style
.
transform
=
"translateY(0)"
;
messageWrapper
.
value
.
style
.
transition
=
"none"
;
}
});
}
else
{
extendedList
.
value
=
[...
props
.
msgList
,
...
props
.
msgList
];
// 实现无缝滚动
nextTick
(()
=>
{
if
(
messageWrapper
.
value
)
{
messageWrapper
.
value
.
style
.
transform
=
"translateY(0)"
;
messageWrapper
.
value
.
style
.
transition
=
"none"
;
}
startScroll
();
});
}
}
</
style
>
};
\ No newline at end of file
// 生命周期钩子
onMounted
(()
=>
{
updateScroll
();
});
onBeforeUnmount
(()
=>
{
stopScroll
();
});
watch
(
()
=>
props
.
msgList
,
()
=>
{
updateScroll
();
},
{
deep
:
true
}
);
</
script
>
<
style
scoped
>
.message-list
{
position
:
relative
;
overflow
:
hidden
;
max-height
:
170px
;
/* 7条 * 50px */
width
:
100%
;
height
:
calc
(
100%
-
22px
);
}
.message-wrapper
{
width
:
100%
;
}
.message-item
{
display
:
flex
;
align-items
:
center
;
font-size
:
14px
;
height
:
32px
;
line-height
:
32px
;
padding
:
1px
0
;
max-width
:
100%
;
cursor
:
pointer
;
}
.message-item
:hover
{
background
:
#f0f0f0
;
}
.message-item
.time
{
color
:
#58616b
;
margin-right
:
5px
;
min-width
:
80px
;
flex-shrink
:
0
;
}
.message-item
.title
{
margin-right
:
5px
;
color
:
#0c0b0b
;
font-weight
:
bold
;
}
.message-item
.content
{
flex
:
1
;
color
:
#58616b
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
</
style
>
src/views/dashboard/index.vue
View file @
61b61fd1
...
@@ -28,8 +28,7 @@
...
@@ -28,8 +28,7 @@
</div>
</div>
<div
class=
"map-box"
>
<div
class=
"map-box"
>
<img
src=
"@/assets/map.png"
alt=
""
/>
<map-svg></map-svg>
<div
class=
"spot-box"
></div>
</div>
</div>
</div>
</div>
</
template
>
</
template
>
...
@@ -39,6 +38,7 @@ import { ref, onMounted, onBeforeUnmount, computed, nextTick } from "vue";
...
@@ -39,6 +38,7 @@ import { ref, onMounted, onBeforeUnmount, computed, nextTick } from "vue";
import
{
useRoute
,
useRouter
}
from
"vue-router"
;
import
{
useRoute
,
useRouter
}
from
"vue-router"
;
import
msgItem
from
"./components/msg-item.vue"
;
import
msgItem
from
"./components/msg-item.vue"
;
import
chartLine
from
"./components/chart-line.vue"
;
import
chartLine
from
"./components/chart-line.vue"
;
import
mapSvg
from
"./components/map-svg.vue"
;
const
percentageO
=
ref
(
20
);
const
percentageO
=
ref
(
20
);
const
percentageT
=
ref
(
62
);
const
percentageT
=
ref
(
62
);
...
@@ -61,8 +61,7 @@ const msgList = ref([
...
@@ -61,8 +61,7 @@ const msgList = ref([
},
},
{
{
title
:
"2#除尘器"
,
title
:
"2#除尘器"
,
content
:
content
:
"除尘器脉冲阀故障或者提升阀故障"
,
"除尘器脉冲阀故障或者提升阀故障"
,
time
:
"05-18 08:00"
,
time
:
"05-18 08:00"
,
},
},
{
{
...
@@ -133,6 +132,7 @@ onBeforeUnmount(() => {});
...
@@ -133,6 +132,7 @@ onBeforeUnmount(() => {});
align-items
:
center
;
align-items
:
center
;
justify-content
:
space-between
;
justify-content
:
space-between
;
height
:
15rem
;
height
:
15rem
;
&
>
div
{
&
>
div
{
background
:
#ffffff
;
background
:
#ffffff
;
border-radius
:
6px
;
border-radius
:
6px
;
...
@@ -140,6 +140,7 @@ onBeforeUnmount(() => {});
...
@@ -140,6 +140,7 @@ onBeforeUnmount(() => {});
padding
:
16px
;
padding
:
16px
;
box-sizing
:
border-box
;
box-sizing
:
border-box
;
}
}
.title
{
.title
{
font-size
:
18px
;
font-size
:
18px
;
font-weight
:
normal
;
font-weight
:
normal
;
...
@@ -147,6 +148,7 @@ onBeforeUnmount(() => {});
...
@@ -147,6 +148,7 @@ onBeforeUnmount(() => {});
line-height
:
22px
;
line-height
:
22px
;
margin-bottom
:
10px
;
margin-bottom
:
10px
;
}
}
.msg-box
{
.msg-box
{
width
:
calc
(
38%
-
16px
);
width
:
calc
(
38%
-
16px
);
height
:
100%
;
height
:
100%
;
...
@@ -155,6 +157,7 @@ onBeforeUnmount(() => {});
...
@@ -155,6 +157,7 @@ onBeforeUnmount(() => {});
.indicators-box
{
.indicators-box
{
width
:
24%
;
width
:
24%
;
height
:
100%
;
height
:
100%
;
.indicators-num
{
.indicators-num
{
font-size
:
37px
;
font-size
:
37px
;
font-weight
:
bold
;
font-weight
:
bold
;
...
@@ -162,6 +165,7 @@ onBeforeUnmount(() => {});
...
@@ -162,6 +165,7 @@ onBeforeUnmount(() => {});
line-height
:
44px
;
line-height
:
44px
;
margin-bottom
:
10px
;
margin-bottom
:
10px
;
}
}
.indicators-item
{
.indicators-item
{
height
:
22px
;
height
:
22px
;
font-size
:
15px
;
font-size
:
15px
;
...
@@ -170,6 +174,7 @@ onBeforeUnmount(() => {});
...
@@ -170,6 +174,7 @@ onBeforeUnmount(() => {});
line-height
:
22px
;
line-height
:
22px
;
}
}
}
}
.line-box
{
.line-box
{
width
:
calc
(
38%
-
16px
);
width
:
calc
(
38%
-
16px
);
height
:
100%
;
height
:
100%
;
...
@@ -186,14 +191,6 @@ onBeforeUnmount(() => {});
...
@@ -186,14 +191,6 @@ onBeforeUnmount(() => {});
box-shadow
:
0px
3px
6px
0px
rgba
(
13
,
15
,
18
,
0
.1
);
box-shadow
:
0px
3px
6px
0px
rgba
(
13
,
15
,
18
,
0
.1
);
padding
:
16px
;
padding
:
16px
;
box-sizing
:
border-box
;
box-sizing
:
border-box
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
img
{
display
:
block
;
width
:
auto
;
height
:
100%
;
}
}
}
}
}
</
style
>
</
style
>
src/views/dustOverview/index.vue
0 → 100644
View file @
61b61fd1
<
template
>
<div
class=
"page-container dust-container"
>
<div
class=
"header"
>
<div
class=
"item-box"
>
<img
src=
"@/assets/icons/warn.png"
alt=
"dust"
/>
<div
class=
"title"
>
<span>
泄漏告警(条)
</span>
<div
class=
"content"
>
6
</div>
</div>
</div>
<div
class=
"item-box"
>
<img
src=
"@/assets/icons/health.png"
alt=
"dust"
/>
<div
class=
"title"
>
<span>
综合健康度
</span>
<div
class=
"content"
>
98%
</div>
</div>
</div>
<div
class=
"item-box"
>
<img
src=
"@/assets/icons/close.png"
alt=
"dust"
/>
<div
class=
"title"
>
<span>
闭环(条)
</span>
<div
class=
"content"
>
6
</div>
</div>
</div>
</div>
<div
class=
"content-box"
>
<div
class=
"search"
>
<el-form
:inline=
"true"
:model=
"formInline"
class=
"demo-form-inline"
>
<el-form-item
label=
"工序"
>
<el-select
v-model=
"formInline.region"
placeholder=
"请选择工序"
style=
"width: 120px"
clearable
>
<el-option
v-for=
"item in options"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"除尘器名称"
>
<el-input
v-model=
"formInline.deviceName"
placeholder=
"请输入除尘器名称"
style=
"width: 200px"
clearable
/>
</el-form-item>
<el-form-item>
<el-button
type=
"default"
class=
"default-btn"
@
click=
"onSubmit"
>
重置
</el-button
>
<el-button
type=
"primary"
class=
"search-btn"
@
click=
"onSubmit"
>
查询
</el-button
>
<el-button
type=
"success"
class=
"add-btn"
@
click=
"onSubmit"
>
新增
</el-button
>
</el-form-item>
</el-form>
</div>
<el-table
:data=
"tableData"
style=
"width: 100%"
>
<el-table-column
v-for=
"item in tableColumns"
:key=
"item.prop"
:prop=
"item.prop"
:label=
"item.label"
/>
</el-table>
</div>
</div>
</
template
>
<
script
setup
>
import
{
ref
,
onMounted
,
onBeforeUnmount
,
computed
,
nextTick
}
from
"vue"
;
const
formInline
=
ref
({
deviceName
:
""
,
region
:
1
,
});
const
options
=
ref
([
{
value
:
"1"
,
label
:
"转炉"
,
},
{
value
:
"2"
,
label
:
"炼铁"
,
},
]);
const
tableColumns
=
ref
([
{
prop
:
"date"
,
label
:
"Date"
,
},
{
prop
:
"name"
,
label
:
"Name"
,
},
]);
const
tableData
=
[
{
date
:
"2016-05-03"
,
name
:
"Tom"
,
state
:
"California"
,
city
:
"Los Angeles"
,
address
:
"No. 189, Grove St, Los Angeles"
,
zip
:
"CA 90036"
,
},
{
date
:
"2016-05-02"
,
name
:
"Tom"
,
state
:
"California"
,
city
:
"Los Angeles"
,
address
:
"No. 189, Grove St, Los Angeles"
,
zip
:
"CA 90036"
,
},
{
date
:
"2016-05-04"
,
name
:
"Tom"
,
state
:
"California"
,
city
:
"Los Angeles"
,
address
:
"No. 189, Grove St, Los Angeles"
,
zip
:
"CA 90036"
,
},
{
date
:
"2016-05-01"
,
name
:
"Tom"
,
state
:
"California"
,
city
:
"Los Angeles"
,
address
:
"No. 189, Grove St, Los Angeles"
,
zip
:
"CA 90036"
,
},
{
date
:
"2016-05-08"
,
name
:
"Tom"
,
state
:
"California"
,
city
:
"Los Angeles"
,
address
:
"No. 189, Grove St, Los Angeles"
,
zip
:
"CA 90036"
,
},
{
date
:
"2016-05-06"
,
name
:
"Tom"
,
state
:
"California"
,
city
:
"Los Angeles"
,
address
:
"No. 189, Grove St, Los Angeles"
,
zip
:
"CA 90036"
,
},
{
date
:
"2016-05-07"
,
name
:
"Tom"
,
state
:
"California"
,
city
:
"Los Angeles"
,
address
:
"No. 189, Grove St, Los Angeles"
,
zip
:
"CA 90036"
,
},
];
const
onSubmit
=
()
=>
{
console
.
log
(
"submit!"
,
formInline
.
value
);
};
onMounted
(
async
()
=>
{});
onBeforeUnmount
(()
=>
{});
</
script
>
<
style
lang=
"scss"
scoped
>
.dust-container
{
width
:
100%
;
height
:
calc
(
100%
-
14px
);
box-sizing
:
border-box
;
.header
{
display
:
flex
;
// justify-content: space-between;
align-items
:
center
;
gap
:
16px
;
.item-box
{
flex
:
1
;
max-width
:
420px
;
height
:
130px
;
background-color
:
#fff
;
border
:
1
.5px
solid
#e8e8e8
;
border-radius
:
6px
;
box-shadow
:
0px
1
.33px
16px
0px
rgba
(
83
,
100
,
170
,
0
.1
);
padding
:
16px
;
box-sizing
:
border-box
;
display
:
flex
;
align-items
:
center
;
img
{
width
:
72px
;
height
:
72px
;
margin-right
:
20px
;
}
.title
{
width
:
100%
;
span
{
color
:
rgba
(
36
,
48
,
71
,
0
.75
);
line-height
:
22px
;
font-size
:
14px
;
font-weight
:
500
;
}
}
.content
{
color
:
#273849
;
line-height
:
30px
;
font-size
:
42px
;
font-weight
:
600
;
margin-top
:
10px
;
}
}
}
.content-box
{
margin-top
:
24px
;
.search
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
margin-bottom
:
16px
;
}
}
.default-btn
{
width
:
85px
;
}
.search-btn
{
width
:
85px
;
background
:
#2182a0
;
border
:
1px
solid
#2182a0
;
}
.add-btn
{
width
:
85px
;
}
}
</
style
>
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