Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
Z
zhmes-agecal
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
耿迪迪
zhmes-agecal
Commits
30fe2086
Commit
30fe2086
authored
Jun 14, 2025
by
wanghao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1 老化柜 和 老化层 界面实现中;
parent
128bf1d7
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
308 additions
and
105 deletions
+308
-105
AgingLayer.vue
zhmes-agecal-web/src/views/screen/components/AgingLayer.vue
+308
-105
No files found.
zhmes-agecal-web/src/views/screen/components/AgingLayer.vue
View file @
30fe2086
<
template
>
<div
class=
"screen-container"
>
<!-- 标题 -->
<div
class=
"title"
ref=
"title"
>
2号柜
</div>
<!-- 柜体容器 -->
<div
class=
"cabinet-body"
>
<div
class=
"cabinet"
ref=
"cabinetContainer"
>
<div
v-for=
"(layer, index) in layers"
:key=
"layer.name"
class=
"layer"
:style=
"getLayerStyle(index)"
:class=
"['layer-depth', `layer-$
{index}`]"
>
{{
layer
.
name
}}
<!-- 整体容器 -->
<div
class=
"content-container"
>
<!-- 柜体容器 -->
<div
class=
"cabinet-body"
>
<!-- 标题 -->
<div
class=
"title"
ref=
"title"
>
2号柜
</div>
<div
class=
"cabinet-and-lines"
>
<!-- 柜体 -->
<div
class=
"cabinet"
ref=
"cabinetContainer"
>
<div
v-for=
"(layer, index) in layers"
:key=
"layer.name"
class=
"layer"
:style=
"getLayerStyle(index)"
:class=
"['layer-depth', `layer-$
{index}`]"
@click="selectLayer(index)"
>
{{
layer
.
name
}}
</div>
</div>
</div>
</div>
<!-- 新增:竖直连线容器 -->
<div
class=
"vertical-line-container"
ref=
"verticalLineContainer"
>
<div
v-for=
"(_, index) in layers"
:key=
"'vline'+index"
class=
"vertical-connector-line"
:ref=
"el => setVerticalLineRef(el, index)"
></div>
<!-- 右侧内容区域 -->
<div
class=
"right-content"
>
<div
class=
"panel-title"
>
托盘信息
</div>
<div
class=
"placeholder"
>
<div
class=
"tray-container"
>
<!-- 托盘信息展示区域 -->
<div
class=
"tray-header"
>
<span
class=
"tray-label"
>
托盘
</span>
<span
class=
"tray-id"
>
TP-
{{
trayInfo
.
id
}}
</span>
</div>
<div
class=
"tray-info"
>
<div
class=
"info-row"
>
<div
class=
"info-label"
>
所在柜体:
</div>
<div
class=
"info-value"
>
2号柜 -
{{
trayInfo
.
layer
}}
</div>
</div>
<div
class=
"info-row"
>
<div
class=
"info-label"
>
产品型号:
</div>
<div
class=
"info-value"
>
{{
trayInfo
.
productModel
}}
</div>
</div>
<div
class=
"info-row"
>
<div
class=
"info-label"
>
当前状态:
</div>
<div
class=
"info-value"
:class=
"trayInfo.statusClass"
>
{{
trayInfo
.
status
}}
</div>
</div>
<div
class=
"info-row"
>
<div
class=
"info-label"
>
老化时长:
</div>
<div
class=
"info-value"
>
{{
trayInfo
.
agingTime
}}
小时
</div>
</div>
<div
class=
"info-row"
>
<div
class=
"info-label"
>
温度:
</div>
<div
class=
"info-value"
>
{{
trayInfo
.
temperature
}}
°C
</div>
</div>
</div>
<!-- 操作按钮区域 -->
<div
class=
"tray-actions"
>
<button
class=
"btn-action btn-load"
@
click=
"loadTray"
>
<i
class=
"icon-load"
></i>
上料
</button>
<button
class=
"btn-action btn-power"
@
click=
"powerOn"
>
<i
class=
"icon-power"
></i>
上电
</button>
</div>
</div>
</div>
</div>
</div>
</div>
...
...
@@ -38,116 +82,117 @@ export default {
layers
:
Array
.
from
({
length
:
10
},
(
_
,
i
)
=>
({
name
:
`第
${
i
+
1
}
层`
,
})),
verticalLineRefs
:
[],
trayInfo
:
{
id
:
"202307-015"
,
layer
:
"第3层"
,
productModel
:
"PQC-1002"
,
status
:
"运行中"
,
statusClass
:
"status-running"
,
agingTime
:
"24"
,
temperature
:
"65"
,
},
};
},
mounted
()
{
this
.
updateVerticalLines
();
window
.
addEventListener
(
'resize'
,
this
.
updateVerticalLines
);
},
beforeDestroy
()
{
window
.
removeEventListener
(
'resize'
,
this
.
updateVerticalLines
);
},
methods
:
{
selectLayer
(
index
)
{
// 模拟选择不同层时托盘信息的变化
this
.
trayInfo
=
{
id
:
`202307-
${(
index
+
1
).
toString
().
padStart
(
3
,
'0'
)}
`
,
layer
:
this
.
layers
[
index
].
name
,
productModel
:
`PQC-
${
1000
+
index
}
`
,
status
:
index
%
3
===
0
?
"待机"
:
"运行中"
,
statusClass
:
index
%
3
===
0
?
"status-idle"
:
"status-running"
,
agingTime
:
(
24
+
index
).
toString
(),
temperature
:
(
65
+
index
).
toString
(),
};
},
loadTray
()
{
this
.
$message
.
success
(
"上料操作已执行"
);
},
powerOn
()
{
this
.
$message
.
success
(
"上电操作已执行"
);
},
getLayerStyle
(
index
)
{
const
verticalSpacing
=
70
;
return
{
bottom
:
`
${
index
*
verticalSpacing
}
px`
,
top
:
`
${
index
*
verticalSpacing
}
px`
,
width
:
'180px'
,
height
:
'60px'
,
zIndex
:
10
-
index
,
zIndex
:
index
,
};
},
setVerticalLineRef
(
el
,
index
)
{
this
.
verticalLineRefs
[
index
]
=
el
;
},
updateVerticalLines
()
{
const
titleEl
=
this
.
$refs
.
title
;
const
cabinetEl
=
this
.
$refs
.
cabinetContainer
;
if
(
!
titleEl
||
!
cabinetEl
)
return
;
const
titleRect
=
titleEl
.
getBoundingClientRect
();
// 标题中心右侧点
const
startX
=
titleRect
.
right
;
const
startY
=
titleRect
.
top
+
titleRect
.
height
/
2
;
for
(
let
i
=
0
;
i
<
this
.
layers
.
length
;
i
++
)
{
const
layerEl
=
cabinetEl
.
children
[
i
];
if
(
!
layerEl
)
continue
;
const
layerRect
=
layerEl
.
getBoundingClientRect
();
// 层左侧中点
const
endX
=
layerRect
.
left
;
const
endY
=
layerRect
.
top
+
layerRect
.
height
/
2
;
const
deltaX
=
endX
-
startX
;
const
deltaY
=
endY
-
startY
;
const
length
=
Math
.
sqrt
(
deltaX
*
deltaX
+
deltaY
*
deltaY
);
const
angle
=
Math
.
atan2
(
deltaY
,
deltaX
)
*
(
180
/
Math
.
PI
);
const
line
=
this
.
verticalLineRefs
[
i
];
if
(
!
line
)
continue
;
line
.
style
.
width
=
`
${
length
}
px`
;
line
.
style
.
height
=
'2px'
;
line
.
style
.
backgroundColor
=
'rgba(100, 200, 255, 0.9)'
;
line
.
style
.
position
=
'absolute'
;
line
.
style
.
left
=
`
${
startX
}
px`
;
line
.
style
.
top
=
`
${
startY
}
px`
;
line
.
style
.
transformOrigin
=
'left center'
;
line
.
style
.
transform
=
`rotate(
${
angle
}
deg)`
;
}
}
}
};
</
script
>
<
style
scoped
>
.screen-container
{
background-color
:
#030b2a
;
color
:
white
;
font-family
:
Arial
,
sans-serif
;
font-family
:
'Arial'
,
sans-serif
;
position
:
relative
;
height
:
100vh
;
display
:
flex
;
align-items
:
center
;
padding-left
:
100px
;
justify-content
:
center
;
padding
:
20px
;
overflow
:
hidden
;
transform-origin
:
center
center
;
background
:
radial-gradient
(
circle
at
center
,
#041740
0%
,
#030b2a
70%
);
}
/* 新增:内容容器 */
.content-container
{
display
:
flex
;
width
:
100%
;
max-width
:
1600px
;
justify-content
:
space-between
;
align-items
:
flex-start
;
padding
:
0
50px
;
}
/* 柜体容器 - 使用Flexbox对齐 */
.cabinet-body
{
display
:
flex
;
align-items
:
flex-start
;
height
:
auto
;
position
:
relative
;
}
/* 标题样式
:增加边框+背景
*/
/* 标题样式 */
.title
{
font-size
:
24px
;
font-weight
:
bold
;
margin-right
:
50px
;
z-index
:
20
;
position
:
relative
;
padding
:
10px
20px
;
margin-right
:
40px
;
padding
:
10px
30px
;
border-radius
:
8px
;
background
:
linear-gradient
(
to
bottom
,
rgba
(
255
,
255
,
255
,
0.1
),
rgba
(
0
,
0
,
0
,
0.2
));
border
:
1px
solid
rgba
(
100
,
180
,
255
,
0.6
);
box-shadow
:
0
4px
12px
rgba
(
0
,
0
,
0
,
0.6
),
inset
0
0
8px
rgba
(
100
,
200
,
255
,
0.3
);
inset
0
0
12px
rgba
(
100
,
200
,
255
,
0.4
);
height
:
60px
;
display
:
flex
;
align-items
:
center
;
flex-shrink
:
0
;
z-index
:
20
;
position
:
relative
;
transition
:
all
0.3s
ease
;
}
/* 新增:柜体容器 */
.cabinet-body
{
.title
:hover
{
box-shadow
:
0
0
15px
rgba
(
100
,
200
,
255
,
0.6
),
inset
0
0
10px
rgba
(
100
,
220
,
255
,
0.5
);
}
.cabinet-and-lines
{
position
:
relative
;
height
:
100%
;
display
:
flex
;
align-items
:
flex-end
;
z-index
:
10
;
}
.cabinet
{
position
:
relative
;
width
:
180px
;
height
:
80vh
;
margin-left
:
20px
;
height
:
700px
;
}
.layer
{
...
...
@@ -164,6 +209,15 @@ export default {
font-size
:
18px
;
border-radius
:
8px
;
transition
:
all
0.3s
ease
;
cursor
:
pointer
;
}
.layer
:hover
{
background
:
linear-gradient
(
to
bottom
,
rgba
(
100
,
180
,
255
,
0.2
),
rgba
(
0
,
0
,
0
,
0.3
));
box-shadow
:
0
4px
15px
rgba
(
100
,
200
,
255
,
0.4
),
inset
0
0
10px
rgba
(
100
,
220
,
255
,
0.4
);
transform
:
translateY
(
-2px
);
}
.layer-depth
{
...
...
@@ -175,26 +229,175 @@ export default {
rgba
(
100
,
180
,
255
,
0.4
);
}
.layer-9
{
box-shadow
:
0
8px
25px
rgba
(
0
,
150
,
255
,
0.5
),
inset
0
0
15px
rgba
(
100
,
220
,
255
,
0.4
);
/* 右侧内容区域 */
.right-content
{
flex
:
1
;
margin-left
:
80px
;
min-height
:
700px
;
display
:
flex
;
flex-direction
:
column
;
background
:
rgba
(
0
,
30
,
80
,
0.2
);
border-radius
:
12px
;
border
:
1px
solid
rgba
(
100
,
180
,
255
,
0.3
);
padding
:
20px
;
position
:
relative
;
overflow
:
hidden
;
box-shadow
:
0
0
20px
rgba
(
0
,
50
,
120
,
0.3
);
}
.panel-title
{
font-size
:
20px
;
color
:
#64c8ff
;
font-weight
:
bold
;
text-shadow
:
0
0
5px
rgba
(
100
,
200
,
255
,
0.5
);
margin-bottom
:
15px
;
padding-bottom
:
10px
;
border-bottom
:
1px
solid
rgba
(
100
,
180
,
255
,
0.4
);
}
.placeholder
{
padding
:
20px
;
background
:
rgba
(
0
,
30
,
80
,
0.3
);
border
:
1px
solid
rgba
(
100
,
180
,
255
,
0.4
);
border-radius
:
10px
;
font-size
:
18px
;
text-align
:
left
;
width
:
100%
;
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
}
.tray-container
{
display
:
flex
;
flex-direction
:
column
;
height
:
100%
;
position
:
relative
;
}
.tray-header
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
padding
:
10px
15px
;
background
:
rgba
(
0
,
40
,
90
,
0.4
);
border-radius
:
8px
;
border
:
1px
solid
rgba
(
100
,
180
,
255
,
0.5
);
margin-bottom
:
20px
;
}
.tray-label
{
font-size
:
20px
;
font-weight
:
bold
;
color
:
#64c8ff
;
text-shadow
:
0
0
8px
rgba
(
100
,
200
,
255
,
0.6
);
}
.tray-id
{
font-size
:
22px
;
font-weight
:
bold
;
background
:
linear-gradient
(
to
right
,
#64c8ff
,
#3a7bd5
);
-webkit-background-clip
:
text
;
-webkit-text-fill-color
:
transparent
;
text-shadow
:
0
0
10px
rgba
(
100
,
200
,
255
,
0.4
);
}
.tray-info
{
flex
:
1
;
padding
:
15px
;
background
:
rgba
(
0
,
30
,
70
,
0.3
);
border-radius
:
8px
;
border
:
1px
solid
rgba
(
100
,
180
,
255
,
0.4
);
}
.info-row
{
display
:
flex
;
margin
:
15px
0
;
padding-bottom
:
10px
;
border-bottom
:
1px
dashed
rgba
(
100
,
180
,
255
,
0.2
);
}
.info-label
{
width
:
100px
;
color
:
#64c8ff
;
font-weight
:
bold
;
}
.info-value
{
flex
:
1
;
color
:
#fff
;
}
.status-idle
{
color
:
#ffcc00
;
font-weight
:
bold
;
}
.status-running
{
color
:
#64ffaa
;
font-weight
:
bold
;
}
.tray-actions
{
display
:
flex
;
justify-content
:
flex-end
;
margin-top
:
20px
;
gap
:
15px
;
}
.btn-action
{
padding
:
12px
25px
;
border-radius
:
6px
;
font-size
:
16px
;
font-weight
:
bold
;
border
:
none
;
cursor
:
pointer
;
transition
:
all
0.3s
ease
;
display
:
flex
;
align-items
:
center
;
gap
:
8px
;
}
.btn-action
:hover
{
transform
:
translateY
(
-3px
);
box-shadow
:
0
5px
15px
rgba
(
0
,
0
,
0
,
0.3
);
}
.btn-load
{
background
:
linear-gradient
(
to
right
,
#3a7bd5
,
#00d2ff
);
color
:
white
;
}
.btn-power
{
background
:
linear-gradient
(
to
right
,
#11998e
,
#38ef7d
);
color
:
white
;
}
.icon-load
,
.icon-power
{
display
:
inline-block
;
width
:
20px
;
height
:
20px
;
background-size
:
contain
;
background-repeat
:
no-repeat
;
}
.icon-load
{
background-image
:
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z'/%3E%3C/svg%3E")
;
}
.icon-power
{
background-image
:
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M16 9v4.66l-3.5 3.51V19h-1v-1.83L8 13.65V9h8m0-6h-2v4h-4V3H8v4h-.01C6.9 6.99 6 7.89 6 8.98v5.52L9.5 18v3h5v-3l3.5-3.5V9c0-1.1-.9-2-2-2V3z'/%3E%3C/svg%3E")
;
}
/*
竖直连线容器
*/
.
vertical-line-container
{
/*
添加光效
*/
.
glow-effect
{
position
:
absolute
;
top
:
0
;
left
:
0
;
width
:
100%
;
height
:
100%
;
background
:
radial-gradient
(
circle
at
center
,
rgba
(
100
,
200
,
255
,
0.1
)
0%
,
transparent
70%
);
pointer-events
:
none
;
z-index
:
10
;
}
.vertical-connector-line
{
position
:
absolute
;
content
:
''
;
height
:
2px
;
z-index
:
-1
;
}
</
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