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
51fd1539
Commit
51fd1539
authored
May 19, 2025
by
Cai Wei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(*): 首页开发
parent
7a56a91f
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
472 additions
and
4 deletions
+472
-4
package-lock.json
package-lock.json
+23
-0
package.json
package.json
+1
-0
map.png
src/assets/map.png
+0
-0
map2.png
src/assets/map2.png
+0
-0
index.vue
src/layout/index.vue
+1
-1
chart.js
src/utils/chart.js
+60
-0
chart-line.vue
src/views/dashboard/components/chart-line.vue
+41
-0
msg-item.vue
src/views/dashboard/components/msg-item.vue
+149
-0
index.vue
src/views/dashboard/index.vue
+197
-3
No files found.
package-lock.json
View file @
51fd1539
...
...
@@ -10,6 +10,7 @@
"dependencies"
:
{
"axios"
:
"^1.9.0"
,
"crypto-js"
:
"^4.2.0"
,
"echarts"
:
"^5.6.0"
,
"element-plus"
:
"^2.9.10"
,
"js-cookie"
:
"^3.0.5"
,
"path"
:
"^0.12.7"
,
...
...
@@ -1593,6 +1594,15 @@
"node"
:
">= 0.4"
}
},
"node_modules/echarts"
:
{
"version"
:
"5.6.0"
,
"resolved"
:
"https://registry.npmjs.org/echarts/-/echarts-5.6.0.tgz"
,
"integrity"
:
"sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA=="
,
"dependencies"
:
{
"tslib"
:
"2.3.0"
,
"zrender"
:
"5.6.1"
}
},
"node_modules/element-plus"
:
{
"version"
:
"2.9.10"
,
"resolved"
:
"https://registry.npmmirror.com/element-plus/-/element-plus-2.9.10.tgz"
,
...
...
@@ -2504,6 +2514,11 @@
"node"
:
">=8.0"
}
},
"node_modules/tslib"
:
{
"version"
:
"2.3.0"
,
"resolved"
:
"https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz"
,
"integrity"
:
"sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
},
"node_modules/undici-types"
:
{
"version"
:
"6.21.0"
,
"resolved"
:
"https://registry.npmmirror.com/undici-types/-/undici-types-6.21.0.tgz"
,
...
...
@@ -2636,6 +2651,14 @@
"resolved"
:
"https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz"
,
"integrity"
:
"sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g=="
,
"license"
:
"MIT"
},
"node_modules/zrender"
:
{
"version"
:
"5.6.1"
,
"resolved"
:
"https://registry.npmjs.org/zrender/-/zrender-5.6.1.tgz"
,
"integrity"
:
"sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag=="
,
"dependencies"
:
{
"tslib"
:
"2.3.0"
}
}
}
}
package.json
View file @
51fd1539
...
...
@@ -11,6 +11,7 @@
"dependencies"
:
{
"
axios
"
:
"
^1.9.0
"
,
"
crypto-js
"
:
"
^4.2.0
"
,
"
echarts
"
:
"
^5.6.0
"
,
"
element-plus
"
:
"
^2.9.10
"
,
"
js-cookie
"
:
"
^3.0.5
"
,
"
path
"
:
"
^0.12.7
"
,
...
...
src/assets/map.png
0 → 100644
View file @
51fd1539
This diff is collapsed.
Click to expand it.
src/assets/map2.png
0 → 100644
View file @
51fd1539
962 KB
src/layout/index.vue
View file @
51fd1539
...
...
@@ -143,7 +143,7 @@ export default {
height
:
calc
(
100vh
-
4
.0625rem
);
box-sizing
:
border-box
;
overflow
:
hidden
;
padding
:
1
.25rem
1
.25rem
3
.125
rem
;
padding
:
1
.25rem
1
.25rem
2
rem
;
background
:
#e7eef5
;
}
}
...
...
src/utils/chart.js
0 → 100644
View file @
51fd1539
import
{
color
}
from
"echarts"
;
export
const
getLineOption
=
(
xData
=
[],
seriesData
=
[])
=>
({
tooltip
:
{
trigger
:
'axis'
,
},
grid
:
{
left
:
'3%'
,
right
:
'4%'
,
bottom
:
'15%'
,
top
:
'5%'
,
containLabel
:
true
,
},
legend
:
{
data
:
[
'健康度指数(%)'
],
bottom
:
'0%'
,
icon
:
"circle"
,
itemWidth
:
10
,
itemHeight
:
10
,
itemGap
:
10
,
},
xAxis
:
{
type
:
'category'
,
axisTick
:
{
show
:
false
,
},
axisLine
:
{
lineStyle
:
{
color
:
'#E9ECF2'
,
},
},
axisLabel
:
{
color
:
'rgba(0,0,0,0.6)'
,
},
data
:
xData
,
},
yAxis
:
{
type
:
'value'
,
axisLabel
:
{
color
:
'rgba(0,0,0,0.6)'
,
},
splitLine
:
{
lineStyle
:
{
color
:
'#E9ECF2'
,
type
:
'dashed'
,
},
},
},
series
:
[
{
name
:
'健康度指数(%)'
,
type
:
'line'
,
color
:
'#399DFA'
,
data
:
seriesData
,
smooth
:
true
,
},
],
});
\ No newline at end of file
src/views/dashboard/components/chart-line.vue
0 → 100644
View file @
51fd1539
<
template
>
<div
ref=
"chartRef"
class=
"chart-line"
></div>
</
template
>
<
script
setup
>
import
{
onMounted
,
onBeforeUnmount
,
ref
}
from
'vue'
;
import
*
as
echarts
from
'echarts'
;
import
{
getLineOption
}
from
'@/utils/chart'
;
const
chartRef
=
ref
(
null
);
let
chartInstance
=
null
;
const
initChart
=
()
=>
{
if
(
chartRef
.
value
)
{
chartInstance
=
echarts
.
init
(
chartRef
.
value
);
const
xData
=
[
'01'
,
'02'
,
'03'
,
'04'
,
'05'
,
'06'
,
'07'
];
const
seriesData
=
[
120
,
200
,
150
,
80
,
60
,
110
,
120
];
const
option
=
getLineOption
(
xData
,
seriesData
);
chartInstance
.
setOption
(
option
);
}
};
onMounted
(()
=>
{
initChart
();
window
.
addEventListener
(
'resize'
,
()
=>
{
chartInstance
?.
resize
();
});
});
onBeforeUnmount
(()
=>
{
chartInstance
?.
dispose
();
});
</
script
>
<
style
scoped
>
.chart-line
{
width
:
100%
;
height
:
calc
(
100%
-
22px
);
}
</
style
>
\ No newline at end of file
src/views/dashboard/components/msg-item.vue
0 → 100644
View file @
51fd1539
<
template
>
<div
class=
"message-list"
@
mouseenter=
"pauseScroll"
@
mouseleave=
"resumeScroll"
>
<div
class=
"message-wrapper"
ref=
"messageWrapper"
>
<div
class=
"message-item"
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>
</
template
>
<
script
setup
>
import
{
ref
,
onMounted
,
onBeforeUnmount
,
nextTick
,
watch
}
from
'vue'
;
const
props
=
defineProps
({
msgList
:
{
type
:
Array
,
default
:
()
=>
[]
}
});
const
extendedList
=
ref
([]);
const
messageWrapper
=
ref
(
null
);
const
itemHeight
=
34
;
// 一条消息高度
const
scrollInterval
=
3000
;
// 每 2 秒滚动一次
let
timer
=
null
;
let
isPaused
=
false
;
// 滚动逻辑:每 2 秒滚动一条(50px)
const
startScroll
=
()
=>
{
stopScroll
();
const
wrapper
=
messageWrapper
.
value
;
if
(
!
wrapper
)
return
;
timer
=
setInterval
(()
=>
{
if
(
isPaused
)
return
;
const
currentTop
=
parseInt
(
wrapper
.
style
.
transform
.
replace
(
'translateY('
,
''
).
replace
(
'px)'
,
''
))
||
0
;
const
nextTop
=
currentTop
-
itemHeight
;
wrapper
.
style
.
transition
=
'transform 0.5s'
;
wrapper
.
style
.
transform
=
`translateY(
${
nextTop
}
px)`
;
const
listHeight
=
(
extendedList
.
value
.
length
/
2
)
*
itemHeight
;
if
(
Math
.
abs
(
nextTop
)
>=
listHeight
)
{
// 到底了,重置
setTimeout
(()
=>
{
wrapper
.
style
.
transition
=
'none'
;
wrapper
.
style
.
transform
=
'translateY(0)'
;
},
500
);
// 等待动画完成后重置
}
},
scrollInterval
);
};
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
();
});
}
};
// 生命周期钩子
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%
;
}
.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
>
\ No newline at end of file
src/views/dashboard/index.vue
View file @
51fd1539
<
template
>
<div
class=
"page-container"
>
dashborad
<div
class=
"dashboard-container"
>
<div
class=
"header"
>
<div
class=
"msg-box"
>
<div
class=
"title"
>
AI智能监测
</div>
<msg-item
:msgList=
"msgList"
></msg-item>
</div>
<div
class=
"indicators-box"
>
<div
class=
"title"
>
综合健康度
</div>
<div
class=
"indicators-num"
>
98%
</div>
<div>
<div
class=
"indicators-item"
>
布袋健康度
</div>
<el-progress
:percentage=
"percentageO"
:color=
"customColorMethod"
/>
</div>
<div>
<div
class=
"indicators-item"
>
脉冲阀健康度
</div>
<el-progress
:percentage=
"percentageT"
:color=
"customColorMethod"
/>
</div>
<div>
<div
class=
"indicators-item"
>
提升阀健康度
</div>
<el-progress
:percentage=
"percentageTh"
:color=
"customColorMethod"
/>
</div>
</div>
<div
class=
"line-box"
>
<div
class=
"title"
>
健康度指数
</div>
<chart-line></chart-line>
</div>
</div>
</
template
>
\ No newline at end of file
<div
class=
"map-box"
>
<img
src=
"@/assets/map.png"
alt=
""
/>
<div
class=
"spot-box"
></div>
</div>
</div>
</
template
>
<
script
setup
>
import
{
ref
,
onMounted
,
onBeforeUnmount
,
computed
,
nextTick
}
from
"vue"
;
import
{
useRoute
,
useRouter
}
from
"vue-router"
;
import
msgItem
from
"./components/msg-item.vue"
;
import
chartLine
from
"./components/chart-line.vue"
;
const
percentageO
=
ref
(
20
);
const
percentageT
=
ref
(
62
);
const
percentageTh
=
ref
(
90
);
const
customColors
=
[
{
color
:
"#ff6a6a"
,
percentage
:
60
},
{
color
:
"#f5c701"
,
percentage
:
80
},
{
color
:
"#08c733"
,
percentage
:
100
},
];
const
route
=
useRoute
();
const
router
=
useRouter
();
const
msgList
=
ref
([
{
title
:
"3#除尘器"
,
content
:
"三仓室存在轻微泄漏"
,
time
:
"05-18 12:00"
,
},
{
title
:
"2#除尘器"
,
content
:
"除尘器脉冲阀故障或者提升阀故障"
,
time
:
"05-18 08:00"
,
},
{
title
:
"3#除尘器"
,
content
:
"三仓室存在轻微泄漏"
,
time
:
"05-18 07:00"
,
},
{
title
:
"2#除尘器"
,
content
:
"除尘器脉冲阀故障或者提升阀故障"
,
time
:
"05-18 05:00"
,
},
{
title
:
"3#除尘器"
,
content
:
"三仓室存在轻微泄漏"
,
time
:
"05-18 03:00"
,
},
{
title
:
"2#除尘器"
,
content
:
"除尘器脉冲阀故障或者提升阀故障"
,
time
:
"05-18 02:00"
,
},
{
title
:
"2#除尘器"
,
content
:
"除尘器脉冲阀故障或者提升阀故障"
,
time
:
"05-18 01:00"
,
},
{
title
:
"3#除尘器"
,
content
:
"三仓室存在轻微泄漏"
,
time
:
"05-17 11:00"
,
},
{
title
:
"2#除尘器"
,
content
:
"除尘器脉冲阀故障或者提升阀故障"
,
time
:
"05-16 02:00"
,
},
]);
const
customColorMethod
=
(
percentage
)
=>
{
if
(
percentage
<
60
)
{
return
customColors
[
0
].
color
;
}
if
(
percentage
<
90
)
{
return
customColors
[
1
].
color
;
}
return
customColors
[
2
].
color
;
};
onMounted
(
async
()
=>
{});
onBeforeUnmount
(()
=>
{});
</
script
>
<
style
lang=
"scss"
scoped
>
.dashboard-container
{
width
:
100%
;
height
:
calc
(
100%
-
14px
);
// background: #ffffff;
// border-radius: 6px;
// box-shadow: 0px 3px 6px 0px rgba(13,15,18,0.10);
// padding: 1rem;
box-sizing
:
border-box
;
.header
{
width
:
100%
;
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
height
:
15rem
;
&
>
div
{
background
:
#ffffff
;
border-radius
:
6px
;
box-shadow
:
0px
3px
6px
0px
rgba
(
13
,
15
,
18
,
0
.1
);
padding
:
16px
;
box-sizing
:
border-box
;
}
.title
{
font-size
:
18px
;
font-weight
:
normal
;
color
:
#83868b
;
line-height
:
22px
;
margin-bottom
:
10px
;
}
.msg-box
{
width
:
calc
(
38%
-
16px
);
height
:
100%
;
}
.indicators-box
{
width
:
24%
;
height
:
100%
;
.indicators-num
{
font-size
:
37px
;
font-weight
:
bold
;
color
:
#08c733
;
line-height
:
44px
;
margin-bottom
:
10px
;
}
.indicators-item
{
height
:
22px
;
font-size
:
15px
;
font-weight
:
normal
;
color
:
#919399
;
line-height
:
22px
;
}
}
.line-box
{
width
:
calc
(
38%
-
16px
);
height
:
100%
;
}
}
.map-box
{
position
:
relative
;
width
:
100%
;
height
:
calc
(
100%
-
16rem
);
margin-top
:
1rem
;
background
:
#f5f5f5
;
border-radius
:
6px
;
box-shadow
:
0px
3px
6px
0px
rgba
(
13
,
15
,
18
,
0
.1
);
padding
:
16px
;
box-sizing
:
border-box
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
img
{
display
:
block
;
width
:
auto
;
height
:
100%
;
}
}
}
</
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