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
c6559a4f
Commit
c6559a4f
authored
Aug 02, 2025
by
wanghao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1 机械臂调整
parent
2745cceb
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
810 additions
and
169 deletions
+810
-169
AgingCabinetBoard.vue
...cal-web/src/views/screen/components/AgingCabinetBoard.vue
+115
-60
AgingLayer.vue
zhmes-agecal-web/src/views/screen/components/AgingLayer.vue
+133
-105
RoboticArm.vue
zhmes-agecal-web/src/views/screen/components/RoboticArm.vue
+521
-0
index.vue
zhmes-agecal-web/src/views/screen/index.vue
+41
-4
No files found.
zhmes-agecal-web/src/views/screen/components/AgingCabinetBoard.vue
View file @
c6559a4f
<
template
>
<div
class=
"app-container"
>
<!-- 右上角的图例提示 -->
<div
class=
"legend"
>
<div
class=
"legend-item"
>
<span
class=
"legend-color green"
></span>
运行中
<!-- 外层容器,添加边框样式 -->
<div
class=
"cabinet-board-container"
>
<!-- 标题区域 -->
<div
class=
"board-header"
>
<div
class=
"board-title"
>
<div
class=
"title-text"
>
老化柜看板
</div>
<div
class=
"title-line"
></div>
</div>
</div>
<div
class=
"legend-item"
>
<span
class=
"legend-color red"
></span>
故障
</div>
<div
class=
"legend-item"
>
<span
class=
"legend-color gray"
></span>
空闲
<!-- 右上角的图例提示 -->
<div
class=
"legend"
>
<div
class=
"legend-item"
>
<span
class=
"legend-color green"
></span>
运行中
</div>
<div
class=
"legend-item"
>
<span
class=
"legend-color red"
></span>
故障
</div>
<div
class=
"legend-item"
>
<span
class=
"legend-color gray"
></span>
空闲
</div>
</div>
</div>
<div
style=
"padding: 20px;"
>
<!-- 渲染每一行 -->
<el-row
:gutter=
"20"
v-for=
"(row, rowIndex) in cabinetRows"
:key=
"rowIndex"
>
<!-- 每行渲染6个卡片 -->
<el-col
:span=
"4"
v-for=
"item in row"
:key=
"item.id"
style=
"margin-bottom: 20px; text-align: center;"
>
<!-- 使用 el-tooltip 来提供 hover 提示 -->
<el-tooltip
:content=
"getTooltipContent(item)"
placement=
"top"
<div
class=
"cabinet-content"
>
<!-- 渲染每一行 -->
<el-row
:gutter=
"20"
v-for=
"(row, rowIndex) in cabinetRows"
:key=
"rowIndex"
>
<!-- 每行渲染6个卡片 -->
<el-col
:span=
"4"
v-for=
"item in row"
:key=
"item.id"
style=
"margin-bottom: 20px; text-align: center;"
>
<el-card
:class=
"statusMap[item.deviceStatus]"
style=
"
width: 150px;
height: 150px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
font-weight: bold;"
@
click
.
native=
"handleCardClick(item)"
<!-- 使用 el-tooltip 来提供 hover 提示 -->
<el-tooltip
:content=
"getTooltipContent(item)"
placement=
"top"
>
{{
item
.
id
+
"号柜"
}}
</el-card>
</el-tooltip>
</el-col>
</el-row>
<el-card
:class=
"statusMap[item.deviceStatus]"
style=
"
width: 100px;
height: 100px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
font-weight: bold;"
@
click
.
native=
"handleCardClick(item)"
>
{{
item
.
id
+
"号柜"
}}
</el-card>
</el-tooltip>
</el-col>
</el-row>
</div>
</div>
</div>
</
template
>
<
script
>
import
{
getAgingCabinetAndPowerCheck
}
from
"@/api/testScheduledTasks/testTasks"
;
import
{
getAgingCabinetAndPowerCheck
}
from
"@/api/testScheduledTasks/testTasks"
;
export
default
{
name
:
"AgingCabinetBoard"
,
data
()
{
...
...
@@ -95,7 +105,7 @@ export default {
{
id
:
34
,
deviceStatus
:
'0'
},
{
id
:
35
,
deviceStatus
:
'0'
},
{
id
:
36
,
deviceStatus
:
'0'
},
//
//...
共36个
// 共36个
],
// 状态对应的颜色类名
statusMap
:
{
...
...
@@ -124,7 +134,7 @@ export default {
handleCardClick
(
item
)
{
// 触发事件传递 cabinetId 给父组件
// 3 是 AgingLayer 组件的索引
this
.
$emit
(
'cabinet-click'
,
item
,
3
);
this
.
$emit
(
'cabinet-click'
,
item
,
3
);
},
getTooltipContent
(
item
)
{
switch
(
item
.
deviceStatus
)
{
...
...
@@ -139,18 +149,56 @@ export default {
},
testAgingCabinetAndPowerCheck
()
{
getAgingCabinetAndPowerCheck
().
then
(
response
=>
{
this
.
cabinets
=
response
;
}
);
this
.
cabinets
=
response
;
});
}
}
};
</
script
>
<
style
>
.aging
{
text-align
:
center
;
font-size
:
40px
;
/* 外层容器样式 */
.cabinet-board-container
{
padding
:
20px
;
background
:
rgba
(
4
,
18
,
57
,
0.7
);
border-radius
:
8px
;
box-shadow
:
0
0
20px
rgba
(
0
,
153
,
255
,
0.2
);
border
:
1px
solid
rgba
(
64
,
158
,
255
,
0.3
);
}
/* 标题区域样式 */
.board-header
{
margin-bottom
:
25px
;
padding-bottom
:
15px
;
border-bottom
:
1px
solid
rgba
(
64
,
158
,
255
,
0.3
);
}
.board-title
{
display
:
flex
;
flex-direction
:
column
;
}
.title-text
{
font-size
:
22px
;
font-weight
:
bold
;
color
:
#ffffff
;
letter-spacing
:
1px
;
text-shadow
:
0
0
10px
rgba
(
64
,
158
,
255
,
0.5
);
}
.title-line
{
height
:
3px
;
width
:
100px
;
background
:
linear-gradient
(
to
right
,
#409EFF
,
transparent
);
margin-top
:
8px
;
border-radius
:
2px
;
}
/* 内容区域样式 */
.cabinet-content
{
padding
:
20px
;
}
/* 状态样式保持不变 */
.default
{
background-color
:
#f0f0f0
;
}
...
...
@@ -163,30 +211,29 @@ export default {
color
:
white
;
}
/*
可选:
悬停效果 */
/*
卡片
悬停效果 */
.el-card
:hover
{
box-shadow
:
0
4px
12px
rgba
(
0
,
0
,
0
,
0.1
);
transform
:
translateY
(
-2px
);
transition
:
all
0.2s
ease
;
}
/* 添加更多状态样式 */
/* 图例样式调整 */
.legend
{
position
:
fixed
;
/* 关键:固定定位
*/
top
:
110px
;
right
:
60px
;
position
:
absolute
;
/* 修改为绝对定位,相对于外层容器
*/
top
:
50px
;
/* 调整与顶部距离 */
right
:
40px
;
/* 调整与右侧距离 */
display
:
flex
;
gap
:
15px
;
background-color
:
#fff
;
background-color
:
rgba
(
4
,
18
,
57
,
0.8
);
/* 半透明背景,与整体风格统一 */
padding
:
10px
15px
;
border-radius
:
6px
;
box-shadow
:
0
2px
8px
rgba
(
0
,
0
,
0
,
0.1
);
z-index
:
9999
;
/* 确保在最
上层 */
z-index
:
10
;
/* 确保在内容
上层 */
font-size
:
14px
;
color
:
#
333
;
color
:
#
e0f0ff
;
/* 浅色文字,适应深色背景 */
}
.legend-item
{
display
:
flex
;
align-items
:
center
;
...
...
@@ -211,4 +258,12 @@ export default {
.legend-color.gray
{
background-color
:
#f0f0f0
;
}
/* 调整app-container样式,作为外层容器 */
.app-container
{
position
:
relative
;
background-color
:
#030b2a
;
/* 整体背景色,与其他界面保持一致 */
min-height
:
100vh
;
/* 确保占满全屏高度 */
padding
:
0
;
}
</
style
>
zhmes-agecal-web/src/views/screen/components/AgingLayer.vue
View file @
c6559a4f
<
template
>
<div
class=
"screen-container"
>
<!-- 返回按钮 -->
<div
class=
"back-button"
@
click=
"goBack"
>
<i
class=
"el-icon-back"
></i>
返回老化柜看板
</div>
<!-- 外层容器 - 添加边框 -->
<div
class=
"aging-layer-container"
>
<!-- 头部标题区域 -->
<div
class=
"tray-header"
>
<div
class=
"tray-title"
>
<div
class=
"title-text"
>
{{
modbusDeviceData
.
id
}}
号柜
</div>
<div
class=
"title-line"
></div>
</div>
</div>
<!-- 整体内容容器 -->
<div
class=
"content-container"
>
<!-- 返回按钮 -->
<div
class=
"back-button"
@
click=
"goBack"
>
<i
class=
"el-icon-back"
></i>
返回老化柜看板
</div>
<!-- 整体容器 -->
<div
class=
"content-container"
>
<!-- 柜体容器 -->
<div
class=
"cabinet-body"
>
<!-- 标题 -->
<div
class=
"title"
ref=
"title"
>
{{
modbusDeviceData
.
id
}}
号柜
</div>
<div
class=
"cabinet-and-lines"
>
<!-- 柜体 -->
<div
class=
"cabinet"
ref=
"cabinetContainer"
>
<div
v-for=
"(layer, index) in layers"
:key=
"layer.id"
class=
"layer"
:style=
"getLayerStyle(index)"
:class=
"[
'layer-depth',
`layer-$
{index}`,
getStatusClass(layer.fStatus) // 动态状态类
]"
@click="selectLayer(index)"
>
<div
class=
"layer-content"
>
<div
class=
"layer-name"
>
{{
layer
.
name
}}
</div>
<div
class=
"layer-status"
>
{{
getStatusText
(
layer
.
fStatus
)
}}
</div>
<!-- 柜体容器 -->
<div
class=
"cabinet-body"
>
<div
class=
"cabinet-and-lines"
>
<!-- 柜体 -->
<div
class=
"cabinet"
ref=
"cabinetContainer"
>
<div
v-for=
"(layer, index) in layers"
:key=
"layer.id"
class=
"layer"
:style=
"getLayerStyle(index)"
:class=
"[
'layer-depth',
`layer-$
{index}`,
getStatusClass(layer.fStatus) // 动态状态类
]"
@click="selectLayer(index)"
>
<div
class=
"layer-content"
>
<div
class=
"layer-name"
>
{{
layer
.
name
}}
</div>
<div
class=
"layer-status"
>
{{
getStatusText
(
layer
.
fStatus
)
}}
</div>
</div>
</div>
</div>
</div>
</div>
</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"
>
{{
modbusDeviceData
.
id
}}
号柜 -
{{
trayInfo
.
layer
.
split
(
"-"
)[
1
]
||
'--'
}}
层
</div>
<!-- 右侧内容区域 -->
<div
class=
"right-content"
>
<div
class=
"panel-title"
>
托盘信息
</div>
<div
class=
"placeholder"
>
<div
class=
"tray-container"
>
<!-- 托盘信息展示区域 -->
<div
class=
"tray-header-inner"
>
<span
class=
"tray-label"
>
托盘
</span>
<span
class=
"tray-id"
>
TP-
{{
trayInfo
.
id
||
'--'
}}
</span>
</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 || 'status-idle'"
>
{{
trayInfo
.
status
||
'--'
}}
<div
class=
"tray-info"
>
<div
class=
"info-row"
>
<div
class=
"info-label"
>
所在柜体:
</div>
<div
class=
"info-value"
>
{{
modbusDeviceData
.
id
}}
号柜 -
{{
trayInfo
.
layer
.
split
(
"-"
)[
1
]
||
'--'
}}
层
</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 || 'status-idle'"
>
{{
trayInfo
.
status
||
'--'
}}
</div>
</div>
</div>
<div
class=
"info-row"
>
<div
class=
"info-label"
>
老化开始时间:
</div>
<div
class=
"info-value"
>
{{
formatDateTime
(
trayInfo
.
fAgingStartTime
)
||
'--'
}}
</div>
</div>
<div
class=
"info-row"
>
<div
class=
"info-label"
>
老化时长:
</div>
<div
class=
"info-value aging-time"
>
{{
agingTimeDisplay
}}
</div>
<div
class=
"info-row"
>
<div
class=
"info-label"
>
老化开始时间:
</div>
<div
class=
"info-value"
>
{{
formatDateTime
(
trayInfo
.
fAgingStartTime
)
||
'--'
}}
</div>
</div>
<div
class=
"info-row"
>
<div
class=
"info-label"
>
老化时长:
</div>
<div
class=
"info-value aging-time"
>
{{
agingTimeDisplay
}}
</div>
</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
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>
...
...
@@ -91,7 +99,6 @@
<
script
>
import
{
queryByDepartmentId
}
from
"@/api/storey/storey"
;
import
{
testPowerOutage
}
from
"@/api/testScheduledTasks/testTasks"
;
export
default
{
name
:
"AgingLayer"
,
...
...
@@ -242,7 +249,6 @@ export default {
powerOn
()
{
this
.
$message
.
success
(
"上电操作已执行"
);
testPowerOutage
().
then
(
response
=>
{
if
(
response
.
code
===
200
)
{
this
.
$message
.
success
(
"断电操作已执行"
);
}
...
...
@@ -286,6 +292,48 @@ export default {
</
script
>
<
style
scoped
>
/* 外层容器样式 - 统一边框风格 */
.aging-layer-container
{
width
:
100%
;
padding
:
20px
;
font-family
:
"Helvetica Neue"
,
Helvetica
,
"PingFang SC"
,
"Hiragino Sans GB"
,
Arial
,
sans-serif
;
background
:
rgba
(
4
,
18
,
57
,
0.7
);
border-radius
:
8px
;
box-shadow
:
0
0
20px
rgba
(
0
,
153
,
255
,
0.2
);
border
:
1px
solid
rgba
(
64
,
158
,
255
,
0.3
);
}
/* 头部标题样式 - 与托盘信息管理界面一致 */
.tray-header
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
margin-bottom
:
25px
;
padding-bottom
:
15px
;
border-bottom
:
1px
solid
rgba
(
64
,
158
,
255
,
0.3
);
}
.tray-title
{
display
:
flex
;
flex-direction
:
column
;
}
.title-text
{
font-size
:
22px
;
font-weight
:
bold
;
color
:
#ffffff
;
letter-spacing
:
1px
;
text-shadow
:
0
0
10px
rgba
(
64
,
158
,
255
,
0.5
);
}
.title-line
{
height
:
3px
;
width
:
100px
;
background
:
linear-gradient
(
to
right
,
#409EFF
,
transparent
);
margin-top
:
8px
;
border-radius
:
2px
;
}
/* 状态背景色 */
.status-idle
{
background
:
linear-gradient
(
to
bottom
,
rgba
(
255
,
255
,
255
,
0.15
),
rgba
(
0
,
0
,
0
,
0.2
));
...
...
@@ -341,22 +389,20 @@ export default {
color
:
white
;
font-family
:
'Arial'
,
sans-serif
;
position
:
relative
;
height
:
100vh
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
padding
:
20px
;
overflow
:
hidden
;
background
:
radial-gradient
(
circle
at
center
,
#041740
0%
,
#030b2a
70%
);
}
.content-container
{
position
:
relative
;
/* 使返回按钮相对于此容器定位 */
display
:
flex
;
width
:
100%
;
max-width
:
1600px
;
justify-content
:
space-between
;
align-items
:
flex-start
;
padding
:
0
50px
;
}
.cabinet-body
{
...
...
@@ -366,35 +412,8 @@ export default {
position
:
relative
;
}
.title
{
font-size
:
24px
;
font-weight
:
bold
;
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
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
;
}
.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
;
z-index
:
10
;
}
.cabinet
{
...
...
@@ -481,7 +500,8 @@ export default {
position
:
relative
;
}
.tray-header
{
/* 区分内部托盘标题和外部容器标题 */
.tray-header-inner
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
...
...
@@ -617,17 +637,25 @@ export default {
}
.back-button
{
position
:
absolute
;
top
:
-90px
;
/* 调整顶部距离 */
right
:
15px
;
/* 调整右侧距离 */
cursor
:
pointer
;
margin-bottom
:
20px
;
width
:
145px
;
padding
:
8px
15px
;
background
:
rgba
(
0
,
30
,
80
,
0.3
);
border-radius
:
6px
;
border
:
1px
solid
rgba
(
100
,
180
,
255
,
0.6
);
color
:
#409EFF
;
display
:
inline-flex
;
align-items
:
center
;
transition
:
all
0.3s
;
font-size
:
14px
;
z-index
:
100
;
/* 确保在其他内容上方 */
}
.back-button
:hover
{
color
:
#66b1ff
;
transform
:
translateX
(
-5px
);
}
</
style
>
zhmes-agecal-web/src/views/screen/components/RoboticArm.vue
0 → 100644
View file @
c6559a4f
<
template
>
<div
class=
"robotic-arm-panel"
>
<!-- 状态指示灯 -->
<div
class=
"status-indicator"
>
<div
class=
"status-light"
:class=
"statusClass"
></div>
<div
class=
"status-text"
>
{{
statusText
}}
</div>
</div>
<!-- 主内容区:指令区+机械臂 -->
<div
class=
"main-content"
>
<!-- 左侧:待上料指令 -->
<div
class=
"loading-command"
>
<div
class=
"command-title"
>
待上料指令
</div>
<div
class=
"command-list"
>
<div
v-for=
"(cmd, index) in loadingCommands"
:key=
"index"
class=
"command-item"
>
<div
class=
"cmd-info"
>
<div
class=
"cmd-tray"
>
托盘:
{{
cmd
.
tray
}}
</div>
<div
class=
"cmd-position"
>
位置:
{{
cmd
.
position
}}
</div>
</div>
</div>
</div>
</div>
<!-- 中间:机械臂主体 -->
<div
class=
"arm-center-wrapper"
>
<div
class=
"robotic-arm-container"
>
<div
class=
"robotic-arm"
>
<!-- 机械臂底座 -->
<div
class=
"arm-base"
>
<div
class=
"base-top"
></div>
<div
class=
"base-bottom"
></div>
</div>
<!-- 机械臂关节1 -->
<div
class=
"arm-joint joint-1"
>
<div
class=
"joint-body"
></div>
</div>
<!-- 机械臂臂1 -->
<div
class=
"arm-segment segment-1"
>
<div
class=
"segment-body"
></div>
</div>
<!-- 机械臂关节2 -->
<div
class=
"arm-joint joint-2"
>
<div
class=
"joint-body"
></div>
</div>
<!-- 机械臂臂2 -->
<div
class=
"arm-segment segment-2"
>
<div
class=
"segment-body"
></div>
</div>
<!-- 机械臂夹具 -->
<div
class=
"arm-gripper"
>
<div
class=
"gripper-left"
></div>
<div
class=
"gripper-right"
></div>
</div>
</div>
</div>
</div>
<!-- 右侧:待下料指令 -->
<div
class=
"unloading-command"
>
<div
class=
"command-title"
>
待下料指令
</div>
<div
class=
"command-list"
>
<div
v-for=
"(cmd, index) in unloadingCommands"
:key=
"index"
class=
"command-item"
>
<div
class=
"cmd-info"
>
<div
class=
"cmd-tray"
>
托盘:
{{
cmd
.
tray
}}
</div>
<div
class=
"cmd-position"
>
位置:
{{
cmd
.
position
}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</
template
>
<
script
>
export
default
{
name
:
'RoboticArm'
,
data
()
{
return
{
status
:
'idle'
,
// idle, running, error
loadingCommands
:
[
{
tray
:
'TP-10023'
,
position
:
'A区-3号架'
},
{
tray
:
'TP-10045'
,
position
:
'B区-1号架'
},
{
tray
:
'TP-10067'
,
position
:
'C区-5号架'
},
{
tray
:
'TP-10023'
,
position
:
'A区-3号架'
},
{
tray
:
'TP-10045'
,
position
:
'B区-1号架'
},
{
tray
:
'TP-10067'
,
position
:
'C区-5号架'
},
{
tray
:
'TP-10023'
,
position
:
'A区-3号架'
},
{
tray
:
'TP-10045'
,
position
:
'B区-1号架'
},
{
tray
:
'TP-10067'
,
position
:
'C区-5号架'
},
{
tray
:
'TP-10023'
,
position
:
'A区-3号架'
},
{
tray
:
'TP-10045'
,
position
:
'B区-1号架'
},
{
tray
:
'TP-10067'
,
position
:
'C区-5号架'
}
],
unloadingCommands
:
[
{
tray
:
'TP-10089'
,
position
:
'老化区-1号柜'
},
{
tray
:
'TP-10101'
,
position
:
'老化区-3号柜'
},
{
tray
:
'TP-10089'
,
position
:
'老化区-1号柜'
},
{
tray
:
'TP-10101'
,
position
:
'老化区-3号柜'
},
{
tray
:
'TP-10089'
,
position
:
'老化区-1号柜'
},
{
tray
:
'TP-10101'
,
position
:
'老化区-3号柜'
},
{
tray
:
'TP-10089'
,
position
:
'老化区-1号柜'
},
{
tray
:
'TP-10101'
,
position
:
'老化区-3号柜'
},
{
tray
:
'TP-10101'
,
position
:
'老化区-3号柜'
},
{
tray
:
'TP-10089'
,
position
:
'老化区-1号柜'
},
{
tray
:
'TP-10101'
,
position
:
'老化区-3号柜'
},
{
tray
:
'TP-10089'
,
position
:
'老化区-1号柜'
},
{
tray
:
'TP-10101'
,
position
:
'老化区-3号柜'
}
]
};
},
computed
:
{
statusClass
()
{
return
{
'idle'
:
this
.
status
===
'idle'
,
'running'
:
this
.
status
===
'running'
,
'error'
:
this
.
status
===
'error'
};
},
statusText
()
{
return
{
'idle'
:
'空闲中'
,
'running'
:
'运行中'
,
'error'
:
'故障'
}[
this
.
status
];
}
},
mounted
()
{
this
.
simulateStatus
();
},
methods
:
{
simulateStatus
()
{
setInterval
(()
=>
{
const
statuses
=
[
'idle'
,
'running'
,
'error'
];
const
randomIndex
=
Math
.
floor
(
Math
.
random
()
*
statuses
.
length
);
this
.
status
=
statuses
[
randomIndex
];
},
10000
);
}
}
};
</
script
>
<
style
scoped
>
/* 外层容器:强制填满父元素高度 */
.robotic-arm-panel
{
width
:
100%
;
height
:
100%
;
min-height
:
100%
;
background
:
rgba
(
10
,
20
,
40
,
0.85
);
border-radius
:
12px
;
padding
:
20px
;
display
:
flex
;
flex-direction
:
column
;
border
:
1px
solid
rgba
(
64
,
158
,
255
,
0.3
);
box-shadow
:
0
0
20px
rgba
(
0
,
50
,
120
,
0.3
);
box-sizing
:
border-box
;
/* 关键:包含padding在高度计算内 */
overflow
:
hidden
;
}
/* 状态指示灯区域 */
.status-indicator
{
display
:
flex
;
align-items
:
center
;
margin-bottom
:
20px
;
padding
:
10px
;
background
:
rgba
(
0
,
30
,
60
,
0.4
);
border-radius
:
8px
;
width
:
fit-content
;
}
.status-light
{
width
:
16px
;
height
:
16px
;
border-radius
:
50%
;
margin-right
:
12px
;
box-shadow
:
0
0
10px
currentColor
;
}
.status-light.idle
{
background-color
:
#64ffaa
;
color
:
#64ffaa
;
}
.status-light.running
{
background-color
:
#409EFF
;
color
:
#409EFF
;
animation
:
pulse
1.5s
infinite
;
}
.status-light.error
{
background-color
:
#ff4d4f
;
color
:
#ff4d4f
;
animation
:
blink
1s
infinite
;
}
@keyframes
pulse
{
0
%
{
opacity
:
0.6
;
}
50
%
{
opacity
:
1
;
}
100
%
{
opacity
:
0.6
;
}
}
@keyframes
blink
{
0
%,
100
%
{
opacity
:
1
;
}
50
%
{
opacity
:
0.3
;
}
}
.status-text
{
font-size
:
18px
;
font-weight
:
bold
;
color
:
#64c8ff
;
}
/* 主内容区:填充剩余高度 */
.main-content
{
display
:
flex
;
flex
:
1
;
/* 关键:占据剩余全部高度 */
gap
:
15px
;
min-height
:
0
;
/* 允许flex容器收缩 */
overflow
:
hidden
;
}
/* 机械臂中心容器:保持固定比例和位置 */
.arm-center-wrapper
{
flex
:
1
;
min-width
:
0
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
padding
:
10px
0
;
}
.robotic-arm-container
{
width
:
100%
;
height
:
100%
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
min-height
:
300px
;
/* 确保机械臂有最小显示空间 */
}
.robotic-arm
{
position
:
relative
;
width
:
200px
;
height
:
330px
;
transform
:
scale
(
0.9
);
}
/* 指令区域:自适应高度,超出滚动 */
.loading-command
,
.unloading-command
{
width
:
160px
;
min-width
:
160px
;
background
:
rgba
(
0
,
30
,
60
,
0.4
);
border-radius
:
8px
;
padding
:
12px
;
border
:
1px
solid
rgba
(
64
,
158
,
255
,
0.3
);
display
:
flex
;
flex-direction
:
column
;
height
:
100%
;
/* 关键:填满父容器高度 */
box-sizing
:
border-box
;
/* 包含padding在高度内 */
}
.command-title
{
font-size
:
15px
;
font-weight
:
bold
;
color
:
#64c8ff
;
margin-bottom
:
12px
;
padding-bottom
:
6px
;
border-bottom
:
1px
solid
rgba
(
100
,
180
,
255
,
0.2
);
}
/* 指令列表:自动扩展,超出滚动 */
.command-list
{
flex
:
1
;
/* 关键:占据剩余高度 */
overflow-y
:
auto
;
/* 内容超出时显示滚动条 */
min-height
:
0
;
/* 修复flex子元素高度限制 */
}
.command-list
::-webkit-scrollbar
{
width
:
6px
;
}
.command-list
::-webkit-scrollbar-thumb
{
background
:
rgba
(
64
,
158
,
255
,
0.5
);
border-radius
:
3px
;
}
.command-item
{
padding
:
8px
;
margin-bottom
:
8px
;
background
:
rgba
(
0
,
40
,
80
,
0.3
);
border-radius
:
6px
;
transition
:
all
0.3s
;
border
:
1px
solid
transparent
;
}
.command-item
:hover
{
border-color
:
rgba
(
100
,
200
,
255
,
0.5
);
transform
:
translateY
(
-2px
);
box-shadow
:
0
4px
8px
rgba
(
0
,
0
,
0
,
0.2
);
}
.cmd-info
{
width
:
100%
;
font-size
:
13px
;
}
.cmd-tray
,
.cmd-position
{
margin-bottom
:
4px
;
color
:
#a0d2ff
;
display
:
flex
;
justify-content
:
space-between
;
}
/* 机械臂各部件样式 */
.arm-base
{
position
:
absolute
;
bottom
:
0
;
left
:
50%
;
transform
:
translateX
(
-50%
);
width
:
80px
;
height
:
20px
;
z-index
:
10
;
}
.base-top
{
width
:
100%
;
height
:
10px
;
background
:
#3a506b
;
border-radius
:
5px
5px
0
0
;
box-shadow
:
0
0
10px
rgba
(
0
,
0
,
0
,
0.5
);
}
.base-bottom
{
width
:
120%
;
margin-left
:
-10%
;
height
:
10px
;
background
:
#2c3e50
;
border-radius
:
0
0
8px
8px
;
}
.arm-joint
{
position
:
absolute
;
width
:
40px
;
height
:
40px
;
border-radius
:
50%
;
background
:
linear-gradient
(
145deg
,
#1e2a3a
,
#2c3e50
);
box-shadow
:
0
0
10px
rgba
(
0
,
0
,
0
,
0.5
);
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
z-index
:
9
;
}
.joint-body
{
width
:
30px
;
height
:
30px
;
border-radius
:
50%
;
background
:
#3a506b
;
border
:
2px
solid
#409EFF
;
}
.joint-1
{
bottom
:
20px
;
left
:
50%
;
transform
:
translateX
(
-50%
);
animation
:
rotateJoint1
8s
infinite
linear
;
}
.arm-segment
{
position
:
absolute
;
background
:
#3a506b
;
border
:
1px
solid
rgba
(
64
,
158
,
255
,
0.5
);
box-shadow
:
0
0
10px
rgba
(
0
,
0
,
0
,
0.3
);
transform-origin
:
top
center
;
}
.segment-body
{
height
:
100%
;
background
:
linear-gradient
(
to
right
,
#2c3e50
,
#3a506b
,
#2c3e50
);
border-left
:
1px
solid
rgba
(
100
,
200
,
255
,
0.3
);
border-right
:
1px
solid
rgba
(
100
,
200
,
255
,
0.3
);
}
.segment-1
{
width
:
20px
;
height
:
120px
;
bottom
:
60px
;
left
:
50%
;
transform
:
translateX
(
-50%
);
z-index
:
8
;
animation
:
moveSegment1
8s
infinite
ease-in-out
;
}
.joint-2
{
bottom
:
180px
;
left
:
50%
;
transform
:
translateX
(
-50%
);
animation
:
rotateJoint2
8s
infinite
linear
reverse
;
}
.segment-2
{
width
:
15px
;
height
:
100px
;
bottom
:
220px
;
left
:
50%
;
transform
:
translateX
(
-50%
);
z-index
:
7
;
animation
:
moveSegment2
8s
infinite
ease-in-out
;
}
.arm-gripper
{
position
:
absolute
;
bottom
:
320px
;
left
:
50%
;
transform
:
translateX
(
-50%
);
width
:
40px
;
height
:
30px
;
display
:
flex
;
justify-content
:
space-between
;
z-index
:
6
;
animation
:
moveGripper
8s
infinite
ease-in-out
;
}
.gripper-left
,
.gripper-right
{
width
:
10px
;
height
:
30px
;
background
:
#3a506b
;
border
:
1px
solid
rgba
(
64
,
158
,
255
,
0.5
);
border-radius
:
5px
;
}
.gripper-left
{
transform
:
rotate
(
-15deg
);
}
.gripper-right
{
transform
:
rotate
(
15deg
);
}
/* 机械臂动画 */
@keyframes
rotateJoint1
{
0
%,
100
%
{
transform
:
translateX
(
-50%
)
rotate
(
0deg
);
}
25
%
{
transform
:
translateX
(
-50%
)
rotate
(
45deg
);
}
50
%
{
transform
:
translateX
(
-50%
)
rotate
(
0deg
);
}
75
%
{
transform
:
translateX
(
-50%
)
rotate
(
-45deg
);
}
}
@keyframes
rotateJoint2
{
0
%,
100
%
{
transform
:
translateX
(
-50%
)
rotate
(
0deg
);
}
25
%
{
transform
:
translateX
(
-50%
)
rotate
(
30deg
);
}
50
%
{
transform
:
translateX
(
-50%
)
rotate
(
0deg
);
}
75
%
{
transform
:
translateX
(
-50%
)
rotate
(
-30deg
);
}
}
@keyframes
moveSegment1
{
0
%,
100
%
{
height
:
120px
;
}
50
%
{
height
:
140px
;
}
}
@keyframes
moveSegment2
{
0
%,
100
%
{
height
:
100px
;
}
50
%
{
height
:
80px
;
}
}
@keyframes
moveGripper
{
0
%,
100
%
{
transform
:
translateX
(
-50%
);
}
25
%
{
transform
:
translateX
(
-60%
);
}
75
%
{
transform
:
translateX
(
-40%
);
}
}
/* 响应式调整 */
@media
(
max-width
:
800px
)
{
.main-content
{
flex-direction
:
column
;
align-items
:
center
;
gap
:
15px
;
overflow-y
:
auto
;
}
.arm-center-wrapper
{
width
:
100%
;
min-height
:
350px
;
}
.loading-command
,
.unloading-command
{
width
:
90%
;
max-width
:
300px
;
height
:
auto
;
min-height
:
200px
;
}
}
@media
(
max-width
:
500px
)
{
.robotic-arm
{
transform
:
scale
(
0.8
);
}
.command-title
{
font-size
:
14px
;
}
.cmd-info
{
font-size
:
12px
;
}
}
@media
(
max-width
:
300px
)
{
.robotic-arm
{
transform
:
scale
(
0.7
);
}
.loading-command
,
.unloading-command
{
width
:
100%
;
min-width
:
auto
;
}
}
</
style
>
zhmes-agecal-web/src/views/screen/index.vue
View file @
c6559a4f
...
...
@@ -35,6 +35,11 @@
<!-- 内容展示区域 -->
<div
class=
"content-area"
>
<!-- 左侧机械臂面板 -->
<div
class=
"robotic-scroll-container"
>
<RoboticArm
class=
"robotic-arm-panel"
/>
</div>
<div
class=
"scroll-container"
>
<transition
name=
"fade"
mode=
"out-in"
>
<!--
<component
:is=
"currentComponent"
/>
-->
...
...
@@ -59,13 +64,16 @@ import AgingLayer from './components/AgingLayer'
import
RealTimeData
from
'./components/RealTimeData'
import
TrayBinding
from
"@/views/screen/components/TrayBinding"
;
import
TrayInformation
from
"@/views/screen/components/TrayInformation"
;
import
RoboticArm
from
'./components/RoboticArm.vue'
;
export
default
{
components
:
{
AgingCabinetBoard
,
AgingLayer
,
RealTimeData
,
TrayBinding
,
TrayInformation
TrayInformation
,
RoboticArm
},
data
()
{
return
{
...
...
@@ -286,15 +294,44 @@ export default {
.content-area
{
padding
:
20px
40px
;
flex
:
1
;
min-height
:
calc
(
100vh
-
150px
);
/* 根据实际布局调整 */
min-height
:
calc
(
100vh
-
150px
);
overflow-y
:
auto
;
display
:
flex
;
/* 添加flex布局 */
gap
:
20px
;
/* 添加间距 */
}
.scroll-container
{
max-height
:
calc
(
100vh
-
180px
);
/* 机械臂面板样式 */
.robotic-arm-panel
{
overflow-y
:
auto
;
flex
:
0
0
500px
;
/* 固定宽度 */
min-height
:
calc
(
100vh
-
150px
);
}
.robotic-scroll-container
{
max-height
:
calc
(
100vh
-
150px
);
width
:
500px
;
overflow-y
:
auto
;
padding
:
0
10px
;
}
.robotic-scroll-container
::-webkit-scrollbar
{
width
:
6px
;
}
.robotic-scroll-container
::-webkit-scrollbar-thumb
{
background-color
:
rgba
(
255
,
255
,
255
,
0.3
);
border-radius
:
3px
;
}
.scroll-container
{
flex
:
1
;
max-height
:
calc
(
100vh
-
150px
);
overflow-y
:
auto
;
padding
:
0
0px
;
}
.scroll-container
::-webkit-scrollbar
{
width
:
6px
;
}
...
...
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