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
4198ca5c
Commit
4198ca5c
authored
Mar 14, 2026
by
wanghao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1 机械臂 可以 实时设置 有指令时是否执行的操作。
2 下料 时 柜子断电 导致 指令不执行 调整,把 断电的的柜子的 指令 设置成 断电失败的状态,等柜子修好后继续。
parent
81db12e6
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
306 additions
and
321 deletions
+306
-321
RobotArmCommandController.java
...g/web/controller/equipment/RobotArmCommandController.java
+21
-0
application-dev.yml
zhmes-agecal-admin/src/main/resources/application-dev.yml
+2
-2
application.yml
zhmes-agecal-admin/src/main/resources/application.yml
+6
-6
RobotArmCommand.java
...c/main/java/com/zehong/system/domain/RobotArmCommand.java
+1
-1
RobotArmCommandMapper.java
.../java/com/zehong/system/mapper/RobotArmCommandMapper.java
+2
-0
NettyUdpServerHandler.java
...om/zehong/system/netty/handler/NettyUdpServerHandler.java
+3
-4
IRobotArmCommandService.java
...va/com/zehong/system/service/IRobotArmCommandService.java
+4
-0
RobotArmCommandServiceImpl.java
...ehong/system/service/impl/RobotArmCommandServiceImpl.java
+86
-41
AllCommandHandler.java
...c/main/java/com/zehong/system/task/AllCommandHandler.java
+14
-5
RobotArmCommandMapper.xml
...rc/main/resources/mapper/system/RobotArmCommandMapper.xml
+5
-0
robotArmCommand.js
zhmes-agecal-web/src/api/robotArm/robotArmCommand.js
+15
-0
ManualAutoSwitchRoboticArm.vue
...rc/views/screen/components/ManualAutoSwitchRoboticArm.vue
+147
-262
RoboticArm-nouse.vue
...ecal-web/src/views/screen/components/RoboticArm-nouse.vue
+0
-0
No files found.
zhmes-agecal-admin/src/main/java/com/zehong/web/controller/equipment/RobotArmCommandController.java
View file @
4198ca5c
...
...
@@ -138,6 +138,27 @@ public class RobotArmCommandController extends BaseController
return
toAjax
(
robotArmCommandService
.
updateInstructionExecutionPriority
(
priority
));
}
/**
* 控制机械臂
* @param action
* @return
*/
@GetMapping
(
"/updateAnimationState/{action}"
)
public
AjaxResult
updateAnimationState
(
@PathVariable
(
"action"
)
String
action
)
{
return
toAjax
(
robotArmCommandService
.
updateAnimationState
(
action
));
}
/**
* 短电已修复
* @param robotArmCommandId r
* @return r
*/
@GetMapping
(
"/powerFailureResolved/{robotArmCommandId}"
)
public
AjaxResult
powerFailureResolved
(
@PathVariable
(
"robotArmCommandId"
)
Long
robotArmCommandId
)
{
return
robotArmCommandService
.
powerFailureResolved
(
robotArmCommandId
);
}
/**
* 删除机械臂指令
*/
...
...
zhmes-agecal-admin/src/main/resources/application-dev.yml
View file @
4198ca5c
...
...
@@ -8,7 +8,7 @@ spring:
master
:
url
:
jdbc:mysql://localhost:3306/zh-mes-device-db?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
username
:
root
password
:
z
h@123456
password
:
Z
h@123456
# 从库数据源
slave
:
# 从数据源开关/默认关闭
...
...
zhmes-agecal-admin/src/main/resources/application.yml
View file @
4198ca5c
...
...
@@ -26,7 +26,7 @@ spring:
# 国际化资源文件路径
basename
:
i18n/messages
profiles
:
active
:
test
active
:
dev
# 文件上传
servlet
:
multipart
:
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/domain/RobotArmCommand.java
View file @
4198ca5c
...
...
@@ -36,7 +36,7 @@ public class RobotArmCommand extends BaseEntity
private
String
type
;
/** 状态:0-待执行;1-执行中;2-执行结束(上料就是绑定托盘,下料就是解绑托盘) */
@Excel
(
name
=
"状态:0-待分配位置,1-待执行;2-执行中;3-未上电;4-执行结束(上料就是绑定托盘,下料就是解绑托盘)"
)
@Excel
(
name
=
"状态:0-待分配位置,1-待执行;2-执行中;3-未上电;4-执行结束(上料就是绑定托盘,下料就是解绑托盘)
: 5-断电失败
"
)
private
String
status
;
/** 指令开始执行时间 */
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/mapper/RobotArmCommandMapper.java
View file @
4198ca5c
...
...
@@ -43,6 +43,8 @@ public interface RobotArmCommandMapper
public
List
<
RobotArmCommand
>
selectIsRunningCommandByTrayCode
(
String
trayCode
);
public
void
updateStatusPowerOffFailed
(
String
storeyCode
);
/**
* 新增机械臂指令
*
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/netty/handler/NettyUdpServerHandler.java
View file @
4198ca5c
...
...
@@ -241,7 +241,9 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
// 完成指令
robotArmCommandService
.
completeCommand
(
commandIdToComplete
);
log
.
info
(
"指令完成: {}"
,
commandIdToComplete
);
}
catch
(
Exception
e
)
{
log
.
error
(
"指令完成失败: {}"
,
commandIdToComplete
,
e
);
}
finally
{
// 清空当前指令
currentCommandId
=
null
;
...
...
@@ -252,9 +254,6 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
synchronized
(
this
)
{
handleFullyIdleState
();
}
}
catch
(
Exception
e
)
{
log
.
error
(
"指令完成失败: {}"
,
commandIdToComplete
,
e
);
commandState
.
set
(
CommandState
.
ERROR
);
}
}
}
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/service/IRobotArmCommandService.java
View file @
4198ca5c
...
...
@@ -69,6 +69,10 @@ public interface IRobotArmCommandService
public
int
updateInstructionExecutionPriority
(
String
priority
);
public
int
updateAnimationState
(
String
action
);
public
AjaxResult
powerFailureResolved
(
Long
robotArmCommandId
);
/**
* 批量删除机械臂指令
*
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/service/impl/RobotArmCommandServiceImpl.java
View file @
4198ca5c
...
...
@@ -105,6 +105,15 @@ public class RobotArmCommandServiceImpl implements IRobotArmCommandService
if
(
cacheObject
!=
null
)
{
priority
=
(
String
)
cacheObject
;
}
Object
cacheObject1
=
redisCache
.
getCacheObject
(
"sys_config:robotAction"
);
String
action
=
"start"
;
if
(
cacheObject1
!=
null
)
{
action
=
(
String
)
cacheObject1
;
}
if
(
"start"
.
equals
(
action
))
{
// 合并查询:同时获取上料、下料各1条待执行指令
List
<
RobotArmCommand
>
pendingCommands
=
robotArmCommandMapper
.
selectPendingLoadUnloadCommands
();
...
...
@@ -155,6 +164,7 @@ public class RobotArmCommandServiceImpl implements IRobotArmCommandService
}
}
}
}
private
void
sendCommand
(
RobotArmCommand
command
,
String
commandType
)
{
...
...
@@ -659,6 +669,41 @@ public class RobotArmCommandServiceImpl implements IRobotArmCommandService
return
1
;
}
/**
* 修改动画状态
*
* @param action 动作
* @return 结果
*/
@Override
public
int
updateAnimationState
(
String
action
)
{
redisCache
.
setCacheObject
(
"sys_config:robotAction"
,
action
);
return
1
;
}
/**
* 恢复电源故障
*
* @param robotArmCommandId r
* @return r
*/
@Override
public
AjaxResult
powerFailureResolved
(
Long
robotArmCommandId
)
{
if
(
robotArmCommandId
==
null
)
{
return
AjaxResult
.
error
(
"参数错误"
);
}
RobotArmCommand
robotArmCommand
=
new
RobotArmCommand
();
robotArmCommand
.
setRobotArmCommandId
(
robotArmCommandId
);
robotArmCommand
.
setStatus
(
"1"
);
robotArmCommandMapper
.
updateRobotArmCommand
(
robotArmCommand
);
notifyCommandsUpdate
();
return
AjaxResult
.
success
();
}
/**
* 批量删除机械臂指令
*
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/task/AllCommandHandler.java
View file @
4198ca5c
...
...
@@ -9,13 +9,12 @@ import com.zehong.system.domain.SysConfig;
import
com.zehong.system.domain.TEquipmentAlarmData
;
import
com.zehong.system.domain.TStoreyInfo
;
import
com.zehong.system.domain.TTrayInfo
;
import
com.zehong.system.mapper.RobotArmCommandMapper
;
import
com.zehong.system.mapper.TStoreyInfoMapper
;
import
com.zehong.system.mapper.TTrayInfoMapper
;
import
com.zehong.system.modbus.util.Modbus4jUtils
;
import
com.zehong.system.service.ISysConfigService
;
import
com.zehong.system.service.ITEquipmentAlarmDataService
;
import
com.zehong.system.service.ITStoreyInfoService
;
import
com.zehong.system.service.ITTrayInfoService
;
import
com.zehong.system.service.*
;
import
com.zehong.system.service.websocket.RobotArmWebSocketHandler
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
...
...
@@ -54,6 +53,11 @@ public class AllCommandHandler {
@Autowired
private
ISysConfigService
configService
;
@Resource
private
RobotArmCommandMapper
robotArmCommandMapper
;
@Resource
private
RobotArmWebSocketHandler
robotArmWebSocketHandler
;
// 使用常量定义索引,避免魔法数字
private
static
final
int
AGING_STAGE_INDEX
=
3
;
private
static
final
int
DEFAULT_HOURS
=
72
;
...
...
@@ -140,8 +144,8 @@ public class AllCommandHandler {
@Async
// 异步执行
@EventListener
(
PowerOffCommandEvent
.
class
)
public
void
handlePowerOffCommand
(
PowerOffCommandEvent
event
)
{
try
{
String
storeyCode
=
event
.
getDeviceCode
()
+
"-"
+
event
.
getLayer
();
try
{
String
ip
=
event
.
getIp
();
int
port
=
event
.
getPort
();
int
registerOffset
=
event
.
getRegisterOffset
();
...
...
@@ -169,6 +173,11 @@ public class AllCommandHandler {
}
catch
(
ModbusInitException
|
ModbusTransportException
e
)
{
log
.
error
(
"断电指令执行失败 - 设备:{} 层:{}"
,
event
.
getDeviceCode
(),
event
.
getLayer
(),
e
);
//把这个指令状态 改成 断电失败,不影响下面的指令执行
robotArmCommandMapper
.
updateStatusPowerOffFailed
(
storeyCode
);
// 通过WebSocket广播更新
robotArmWebSocketHandler
.
broadcastCommandUpdate
();
// 记录异常
TEquipmentAlarmData
alarmData
=
new
TEquipmentAlarmData
();
alarmData
.
setfAlarmType
(
"03"
);
// 老化层
...
...
zhmes-agecal-system/src/main/resources/mapper/system/RobotArmCommandMapper.xml
View file @
4198ca5c
...
...
@@ -37,6 +37,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include
refid=
"selectRobotArmCommandVo"
/>
where f_tray_code = #{trayCode} and f_status != '4'
</select>
<update
id=
"updateStatusPowerOffFailed"
parameterType=
"string"
>
update t_robot_arm_command
set f_status = '5'
where f_storey_code = #{storeyCode} and f_status = '2'
</update>
<select
id=
"selectRobotArmCommandList"
parameterType=
"RobotArmCommand"
resultMap=
"RobotArmCommandResult"
>
<include
refid=
"selectRobotArmCommandVo"
/>
...
...
zhmes-agecal-web/src/api/robotArm/robotArmCommand.js
View file @
4198ca5c
...
...
@@ -112,6 +112,14 @@ export function delCommand(robotArmCommandId) {
})
}
export
function
powerFailureResolved
(
robotArmCommandId
)
{
return
request
({
url
:
'/robotArm/command/powerFailureResolved/'
+
robotArmCommandId
,
method
:
'get'
})
}
// 导出机械臂指令
export
function
exportCommand
(
query
)
{
return
request
({
...
...
@@ -120,3 +128,10 @@ export function exportCommand(query) {
params
:
query
})
}
export
function
updateAnimationState
(
action
)
{
return
request
({
url
:
'/robotArm/command/updateAnimationState/'
+
action
,
method
:
'get'
})
}
zhmes-agecal-web/src/views/screen/components/ManualAutoSwitchRoboticArm.vue
View file @
4198ca5c
...
...
@@ -2,21 +2,16 @@
<div
class=
"robotic-arm-panel"
>
<!-- 标题区域 -->
<div
class=
"panel-title"
>
<!-- 左侧标题+状态指示灯组合 -->
<div
class=
"title-with-status"
>
<div
class=
"title-left"
>
<div
class=
"title-text"
>
机械臂
</div>
<div
class=
"title-line"
></div>
</div>
<!-- 状态指示灯:紧挨着标题文字右侧 -->
<div
class=
"status-indicator"
>
<div
class=
"status-light"
:class=
"statusClass"
></div>
<div
class=
"status-text"
>
{{
statusText
}}
</div>
</div>
</div>
<!-- 上料按钮 -->
<div
class=
"title-right"
>
<button
class=
"add-button"
@
click=
"openAddModeDialog"
>
<i
class=
"el-icon-plus"
></i>
上料
...
...
@@ -38,16 +33,12 @@
<div
class=
"dialog-content"
>
<div
class=
"mode-selection"
>
<div
class=
"mode-option"
@
click=
"selectMode('auto')"
>
<div
class=
"mode-icon"
>
<i
class=
"el-icon-video-play"
></i>
</div>
<div
class=
"mode-icon"
><i
class=
"el-icon-video-play"
></i></div>
<div
class=
"mode-title"
>
自动模式
</div>
<div
class=
"mode-desc"
>
系统自动分配位置
</div>
</div>
<div
class=
"mode-option"
@
click=
"selectMode('manual')"
>
<div
class=
"mode-icon"
>
<i
class=
"el-icon-s-operation"
></i>
</div>
<div
class=
"mode-icon"
><i
class=
"el-icon-s-operation"
></i></div>
<div
class=
"mode-title"
>
手动模式
</div>
<div
class=
"mode-desc"
>
手动指定层编号
</div>
</div>
...
...
@@ -68,23 +59,13 @@
<div
class=
"dialog-content"
>
<div
class=
"scan-prompt"
>
请扫描托盘二维码
</div>
<div
class=
"mode-indicator"
>
自动模式 - 系统自动分配位置
</div>
<div
class=
"input-group"
>
<label
for=
"trayCode"
>
标检单号:
</label>
<input
type=
"text"
v-model=
"productStandardInspectionNumber"
placeholder=
"手动输入或扫码标检单号"
ref=
"productStandardInspectionNumberInput"
>
<input
type=
"text"
v-model=
"productStandardInspectionNumber"
placeholder=
"手动输入或扫码标检单号"
ref=
"productStandardInspectionNumberInput"
>
</div>
<div
class=
"input-group"
>
<label
for=
"trayCode"
>
托盘编号:
</label>
<input
type=
"text"
v-model=
"trayCode"
placeholder=
"手动输入或扫码"
>
<input
type=
"text"
v-model=
"trayCode"
placeholder=
"手动输入或扫码"
>
</div>
</div>
</div>
...
...
@@ -103,36 +84,18 @@
<div
class=
"dialog-content"
>
<div
class=
"scan-prompt"
>
请输入上料信息
</div>
<div
class=
"mode-indicator"
>
手动模式 - 需要指定层编号
</div>
<div
class=
"manual-inputs"
>
<div
class=
"input-group"
>
<label
for=
"trayCode"
>
标检单号:
</label>
<input
type=
"text"
v-model=
"productStandardInspectionNumber"
placeholder=
"手动输入或扫码标检单号"
ref=
"manualStandardInput"
>
<input
type=
"text"
v-model=
"productStandardInspectionNumber"
placeholder=
"手动输入或扫码标检单号"
ref=
"manualStandardInput"
>
</div>
<div
class=
"input-group"
>
<label
for=
"trayCode"
>
托盘编号:
</label>
<input
id=
"trayCode"
type=
"text"
v-model=
"manualTrayCode"
placeholder=
"输入托盘编号"
>
<input
id=
"trayCode"
type=
"text"
v-model=
"manualTrayCode"
placeholder=
"输入托盘编号"
>
</div>
<div
class=
"input-group"
>
<label
for=
"storeyCode"
>
层编号:
</label>
<input
id=
"storeyCode"
type=
"text"
v-model=
"storeyCode"
placeholder=
"输入层编号(如: 1-1, 12-3)"
>
<input
id=
"storeyCode"
type=
"text"
v-model=
"storeyCode"
placeholder=
"输入层编号(如: 1-1, 12-3)"
>
</div>
</div>
</div>
...
...
@@ -150,13 +113,7 @@
<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"
:class=
"getCommandStatusClass(cmd.status)"
@
click=
"handleCommandClick(cmd)"
>
<div
v-for=
"(cmd, index) in loadingCommands"
:key=
"index"
class=
"command-item"
:class=
"getCommandStatusClass(cmd.status)"
@
click=
"handleCommandClick(cmd)"
>
<div
class=
"cmd-info"
>
<div
class=
"cmd-tray"
>
托盘:
{{
cmd
.
trayCode
}}
</div>
<div
class=
"cmd-position"
>
位置:
{{
cmd
.
position
}}
</div>
...
...
@@ -166,35 +123,23 @@
</div>
</div>
<!-- 中间:机械臂主体 -->
<!-- 中间:机械臂主体
(添加双击事件和暂停类)
-->
<div
class=
"arm-center-wrapper"
>
<!-- 优先级控制区域 -->
<div
class=
"priority-control"
>
<div
class=
"priority-display"
>
{{
priorityDisplayText
}}
</div>
<button
class=
"priority-toggle-btn"
@
click=
"togglePriority"
>
点击切换
</button>
<button
class=
"priority-toggle-btn"
@
click=
"togglePriority"
>
点击切换
</button>
</div>
<div
class=
"robotic-arm-container"
>
<div
class=
"robotic-arm-container"
@
dblclick=
"toggleAnimation"
:class=
"
{ 'paused-animation': !isAnimating }">
<div
class=
"robotic-arm"
>
<!-- 机械臂各部件 -->
<div
class=
"arm-base"
>
<div
class=
"base-top"
></div>
<div
class=
"base-bottom"
></div>
</div>
<div
class=
"arm-joint joint-1"
>
<div
class=
"joint-body"
></div>
</div>
<div
class=
"arm-segment segment-1"
>
<div
class=
"segment-body"
></div>
</div>
<div
class=
"arm-joint joint-2"
>
<div
class=
"joint-body"
></div>
</div>
<div
class=
"arm-segment segment-2"
>
<div
class=
"segment-body"
></div>
</div>
<div
class=
"arm-joint joint-1"
><div
class=
"joint-body"
></div></div>
<div
class=
"arm-segment segment-1"
><div
class=
"segment-body"
></div></div>
<div
class=
"arm-joint joint-2"
><div
class=
"joint-body"
></div></div>
<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>
...
...
@@ -207,13 +152,7 @@
<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"
:class=
"getCommandStatusClass(cmd.status)"
@
click=
"handleCommandClick(cmd)"
>
<div
v-for=
"(cmd, index) in unloadingCommands"
:key=
"index"
class=
"command-item"
:class=
"getCommandStatusClass(cmd.status)"
@
click=
"handleCommandClick(cmd)"
>
<div
class=
"cmd-info"
>
<div
class=
"cmd-tray"
>
托盘:
{{
cmd
.
trayCode
}}
</div>
<div
class=
"cmd-position"
>
位置:
{{
cmd
.
position
}}
</div>
...
...
@@ -245,7 +184,7 @@
</div>
<!-- 确认执行完成对话框 -->
<div
class=
"dialog-mask"
v-if=
"showSureCompleteDialog"
@
click
.
self=
"close
PowerOn
Dialog"
>
<div
class=
"dialog-mask"
v-if=
"showSureCompleteDialog"
@
click
.
self=
"close
SureComplete
Dialog"
>
<div
class=
"dialog-container"
>
<div
class=
"dialog-header"
>
确认执行完成
</div>
<div
class=
"dialog-body"
>
...
...
@@ -263,11 +202,32 @@
</div>
</div>
</div>
<!-- 新增:断电失败修复对话框(状态5) -->
<div
class=
"dialog-mask"
v-if=
"showFixDialog"
@
click
.
self=
"closeFixDialog"
>
<div
class=
"dialog-container"
>
<div
class=
"dialog-header"
>
断电失败
</div>
<div
class=
"dialog-body"
>
<div
class=
"dialog-content"
>
<div
class=
"scan-prompt"
>
该指令断电失败,是否已修复?
</div>
<div
class=
"power-on-info"
>
<div><span
class=
"label"
>
托盘编号:
</span>
{{
selectedFailedCommand
?
selectedFailedCommand
.
trayCode
:
''
}}
</div>
<div><span
class=
"label"
>
位置:
</span>
{{
selectedFailedCommand
?
selectedFailedCommand
.
position
:
''
}}
</div>
</div>
</div>
</div>
<div
class=
"dialog-footer"
>
<button
class=
"cancel-button"
@
click=
"closeFixDialog"
>
取消
</button>
<button
class=
"confirm-button"
@
click=
"handleFixConfirm"
>
是,已修复
</button>
</div>
</div>
</div>
</div>
</
template
>
<
script
>
import
{
addCommand
,
powerOnCommand
,
sendHomeCommand
,
sendStopCommand
,
sureCompletedCommand
,
updateInstructionExecutionPriority
,
addManualCommand
}
from
"@/api/robotArm/robotArmCommand"
import
{
addCommand
,
powerOnCommand
,
sendHomeCommand
,
sendStopCommand
,
sureCompletedCommand
,
updateInstructionExecutionPriority
,
addManualCommand
,
updateAnimationState
,
powerFailureResolved
}
from
"@/api/robotArm/robotArmCommand"
export
default
{
name
:
'RoboticArm'
,
...
...
@@ -281,7 +241,6 @@ export default {
// 自动模式数据
trayCode
:
''
,
// 手动模式数据
manualTrayCode
:
''
,
storeyCode
:
''
,
...
...
@@ -297,6 +256,12 @@ export default {
selectedCommand
:
null
,
priority
:
'loading'
,
// loading: 上料优先, unloading: 下料优先
initWebSocketIp
:
''
,
// 新增:动画控制
isAnimating
:
true
,
// 默认动画运行
// 新增:断电失败修复对话框
showFixDialog
:
false
,
selectedFailedCommand
:
null
,
};
},
computed
:
{
...
...
@@ -362,34 +327,19 @@ export default {
},
methods
:
{
// 打开上料模式选择对话框
openAddModeDialog
()
{
this
.
showModeDialog
=
true
;
},
// 关闭模式选择对话框
closeModeDialog
()
{
this
.
showModeDialog
=
false
;
},
// 选择模式
// ==================== 原有方法保持不变 ====================
openAddModeDialog
()
{
this
.
showModeDialog
=
true
;
},
closeModeDialog
()
{
this
.
showModeDialog
=
false
;
},
selectMode
(
mode
)
{
this
.
showModeDialog
=
false
;
if
(
mode
===
'auto'
)
{
this
.
showAutoAddDialog
=
true
;
}
else
{
this
.
showManualAddDialog
=
true
;
}
if
(
mode
===
'auto'
)
this
.
showAutoAddDialog
=
true
;
else
this
.
showManualAddDialog
=
true
;
},
// 关闭自动模式对话框
closeAutoDialog
()
{
this
.
showAutoAddDialog
=
false
;
this
.
productStandardInspectionNumber
=
''
;
this
.
trayCode
=
''
;
},
// 关闭手动模式对话框
closeManualDialog
()
{
this
.
showManualAddDialog
=
false
;
this
.
manualTrayCode
=
''
;
...
...
@@ -397,85 +347,44 @@ export default {
this
.
trayType
=
'0'
;
this
.
productStandardInspectionNumber
=
''
;
},
// 确认自动模式上料
confirmAutoAdd
()
{
if
(
!
this
.
trayCode
.
trim
())
{
this
.
$message
.
warning
(
'请输入托盘编号'
);
return
;
}
if
(
!
this
.
productStandardInspectionNumber
.
trim
())
{
this
.
$message
.
warning
(
'请输入标检单编号'
);
return
;
}
if
(
!
this
.
trayCode
.
trim
())
{
this
.
$message
.
warning
(
'请输入托盘编号'
);
return
;
}
if
(
!
this
.
productStandardInspectionNumber
.
trim
())
{
this
.
$message
.
warning
(
'请输入标检单编号'
);
return
;
}
const
robotArmCommand
=
{
trayCode
:
this
.
trayCode
,
storeyCode
:
'待分配位置'
,
type
:
'0'
,
productStandardInspectionNumber
:
this
.
productStandardInspectionNumber
};
addCommand
(
robotArmCommand
).
then
(
res
=>
{
if
(
res
.
code
===
200
)
{
this
.
$message
.
success
(
"添加成功"
);
this
.
closeAutoDialog
();
}
else
{
this
.
$message
.
error
(
"添加失败"
);
}
if
(
res
.
code
===
200
)
{
this
.
$message
.
success
(
"添加成功"
);
this
.
closeAutoDialog
();
}
else
{
this
.
$message
.
error
(
"添加失败"
);
}
})
},
// 确认手动模式上料
confirmManualAdd
()
{
if
(
!
this
.
productStandardInspectionNumber
.
trim
())
{
this
.
$message
.
warning
(
'请输入标检单号'
);
return
;
}
if
(
!
this
.
manualTrayCode
.
trim
())
{
this
.
$message
.
warning
(
'请输入托盘编号'
);
return
;
}
if
(
!
this
.
storeyCode
.
trim
())
{
this
.
$message
.
warning
(
'请输入层编号'
);
return
;
}
if
(
!
this
.
productStandardInspectionNumber
.
trim
())
{
this
.
$message
.
warning
(
'请输入标检单号'
);
return
;
}
if
(
!
this
.
manualTrayCode
.
trim
())
{
this
.
$message
.
warning
(
'请输入托盘编号'
);
return
;
}
if
(
!
this
.
storeyCode
.
trim
())
{
this
.
$message
.
warning
(
'请输入层编号'
);
return
;
}
const
robotArmCommand
=
{
trayCode
:
this
.
manualTrayCode
,
storeyCode
:
this
.
storeyCode
,
productStandardInspectionNumber
:
this
.
productStandardInspectionNumber
,
};
addManualCommand
(
robotArmCommand
).
then
(
res
=>
{
if
(
res
.
code
===
200
)
{
this
.
$message
.
success
(
"手动添加成功"
);
this
.
closeManualDialog
();
}
if
(
res
.
code
===
200
)
{
this
.
$message
.
success
(
"手动添加成功"
);
this
.
closeManualDialog
();
}
})
},
initWebSocket
()
{
// 从环境变量获取基础URL,默认使用Nginx代理地址
const
backendUrl
=
process
.
env
.
VUE_APP_API_BASE_URL
||
this
.
initWebSocketIp
;
// 根据需要切换不同的WebSocket端点
const
wsPath
=
'/agecal/ws-robot-arm'
;
// 或 '/agecal/ws-aging-cabinet'
// 替换协议并添加完整路径
const
wsPath
=
'/agecal/ws-robot-arm'
;
const
wsUrl
=
backendUrl
.
replace
(
'http'
,
'ws'
)
+
wsPath
;
try
{
this
.
websocket
=
new
WebSocket
(
wsUrl
);
this
.
websocket
.
onopen
=
()
=>
{
console
.
log
(
'机械臂指令WebSocket连接成功'
);
this
.
status
=
'idle'
;
this
.
sendWebSocketMessage
({
type
:
'request'
,
commands
:
[
'loading'
,
'unloading'
]
});
};
this
.
websocket
.
onmessage
=
(
event
)
=>
{
try
{
const
message
=
JSON
.
parse
(
event
.
data
);
...
...
@@ -484,7 +393,7 @@ export default {
robotArmCommandId
:
cmd
.
robotArmCommandId
,
trayCode
:
cmd
.
trayCode
,
position
:
cmd
.
storeyCode
,
status
:
cmd
.
status
||
'0'
// 默认待执行状态
status
:
cmd
.
status
||
'0'
}));
}
else
if
(
message
.
type
===
'unloading'
)
{
...
...
@@ -492,41 +401,23 @@ export default {
robotArmCommandId
:
cmd
.
robotArmCommandId
,
trayCode
:
cmd
.
trayCode
,
position
:
cmd
.
storeyCode
,
status
:
cmd
.
status
||
'0'
// 默认待执行状态
status
:
cmd
.
status
||
'0'
}));
}
// 新增:处理状态更新消息
else
if
(
message
.
type
===
'status'
)
{
this
.
status
=
message
.
data
;
// 更新机械臂状态
this
.
status
=
message
.
data
;
}
}
catch
(
e
)
{
console
.
error
(
'解析WebSocket消息失败:'
,
e
);
}
};
this
.
websocket
.
onerror
=
(
error
)
=>
{
console
.
error
(
'WebSocket错误:'
,
error
);
this
.
status
=
'error'
;
this
.
scheduleReconnect
();
}
catch
(
e
)
{
console
.
error
(
'解析WebSocket消息失败:'
,
e
);
}
};
this
.
websocket
.
onclose
=
()
=>
{
console
.
log
(
'WebSocket连接关闭'
);
this
.
scheduleReconnect
();
};
}
catch
(
e
)
{
console
.
error
(
'创建WebSocket失败:'
,
e
);
this
.
scheduleReconnect
();
}
this
.
websocket
.
onerror
=
(
error
)
=>
{
console
.
error
(
'WebSocket错误:'
,
error
);
this
.
status
=
'error'
;
this
.
scheduleReconnect
();
};
this
.
websocket
.
onclose
=
()
=>
{
console
.
log
(
'WebSocket连接关闭'
);
this
.
scheduleReconnect
();
};
}
catch
(
e
)
{
console
.
error
(
'创建WebSocket失败:'
,
e
);
this
.
scheduleReconnect
();
}
},
sendWebSocketMessage
(
message
)
{
if
(
this
.
websocket
&&
this
.
websocket
.
readyState
===
WebSocket
.
OPEN
)
{
this
.
websocket
.
send
(
JSON
.
stringify
(
message
));
}
},
scheduleReconnect
()
{
if
(
this
.
reconnectInterval
)
clearInterval
(
this
.
reconnectInterval
);
this
.
reconnectInterval
=
setInterval
(()
=>
{
...
...
@@ -537,132 +428,116 @@ export default {
}
},
5000
);
},
disconnectWebSocket
()
{
if
(
this
.
websocket
)
{
try
{
this
.
websocket
.
close
();
}
catch
(
e
)
{
console
.
error
(
'关闭WebSocket时出错:'
,
e
);
}
}
if
(
this
.
reconnectInterval
)
{
clearInterval
(
this
.
reconnectInterval
);
this
.
reconnectInterval
=
null
;
}
if
(
this
.
websocket
)
{
try
{
this
.
websocket
.
close
();
}
catch
(
e
)
{
console
.
error
(
'关闭WebSocket时出错:'
,
e
);
}
}
if
(
this
.
reconnectInterval
)
{
clearInterval
(
this
.
reconnectInterval
);
this
.
reconnectInterval
=
null
;
}
this
.
websocket
=
null
;
},
// 回零
handleHome
()
{
sendHomeCommand
().
then
(
response
=>
{
this
.
$message
.
success
(
"已发送"
);
})
},
// 停止
handleStop
()
{
sendStopCommand
().
then
(
response
=>
{
this
.
$message
.
success
(
"已发送"
);
})
},
// 更新状态文本映射
handleHome
()
{
sendHomeCommand
().
then
(
response
=>
{
this
.
$message
.
success
(
"已发送"
);
})
},
handleStop
()
{
sendStopCommand
().
then
(
response
=>
{
this
.
$message
.
success
(
"已发送"
);
})
},
getStatusText
(
status
)
{
const
statusMap
=
{
'0'
:
'待分配位置'
,
'1'
:
'待执行'
,
'2'
:
'执行中'
,
'3'
:
'未上电'
,
'4'
:
'执行结束'
};
const
statusMap
=
{
'0'
:
'待分配位置'
,
'1'
:
'待执行'
,
'2'
:
'执行中'
,
'3'
:
'未上电'
,
'4'
:
'执行结束'
,
'5'
:
'断电失败'
};
return
statusMap
[
status
]
||
'未知状态'
;
},
// 更新状态样式类映射
getCommandStatusClass
(
status
)
{
return
{
'status-0'
:
status
==
'0'
,
// 待分配位置
'status-1'
:
status
==
'1'
,
// 待执行
'status-2'
:
status
==
'2'
,
// 执行中
'status-3'
:
status
==
'3'
,
// 未上电
'status-4'
:
status
==
'4'
// 执行结束
'status-0'
:
status
==
'0'
,
'status-1'
:
status
==
'1'
,
'status-2'
:
status
==
'2'
,
'status-3'
:
status
==
'3'
,
'status-4'
:
status
==
'4'
,
'status-5'
:
status
===
'5'
};
},
// ==================== 修改:handleCommandClick 增加对 status === '5' 的处理 ====================
handleCommandClick
(
cmd
)
{
// 只有未上电状态的指令才可点击
if
(
cmd
.
status
===
'3'
)
{
this
.
selectedCommand
=
cmd
;
this
.
showPowerOnDialog
=
true
;
}
else
if
(
cmd
.
status
===
'2'
)
{
}
else
if
(
cmd
.
status
===
'2'
)
{
this
.
selectedCommand
=
cmd
;
this
.
showSureCompleteDialog
=
true
;
}
else
if
(
cmd
.
status
===
'5'
)
{
// 新增:断电失败
this
.
selectedFailedCommand
=
cmd
;
this
.
showFixDialog
=
true
;
}
},
closeSureCompleteDialog
()
{
this
.
showSureCompleteDialog
=
false
;
this
.
selectedCommand
=
null
;
},
closePowerOnDialog
()
{
this
.
showPowerOnDialog
=
false
;
this
.
selectedCommand
=
null
;
},
closeSureCompleteDialog
()
{
this
.
showSureCompleteDialog
=
false
;
this
.
selectedCommand
=
null
;
},
closePowerOnDialog
()
{
this
.
showPowerOnDialog
=
false
;
this
.
selectedCommand
=
null
;
},
confirmSureComplete
()
{
if
(
!
this
.
selectedCommand
)
return
;
sureCompletedCommand
(
this
.
selectedCommand
.
robotArmCommandId
).
then
(
res
=>
{
if
(
res
.
code
===
200
)
{
this
.
$message
.
success
(
"确认完成成功"
);
this
.
closeSureCompleteDialog
();
}
else
{
this
.
$message
.
error
(
"确认完成失败"
);
}
}).
catch
(
err
=>
{
this
.
$message
.
error
(
"确认完成失败"
);
})
if
(
res
.
code
===
200
)
{
this
.
$message
.
success
(
"确认完成成功"
);
this
.
closeSureCompleteDialog
();
}
else
{
this
.
$message
.
error
(
"确认完成失败"
);
}
}).
catch
(
err
=>
{
this
.
$message
.
error
(
"确认完成失败"
);
})
},
confirmPowerOn
()
{
if
(
!
this
.
selectedCommand
)
return
;
powerOnCommand
(
this
.
selectedCommand
.
robotArmCommandId
).
then
(
res
=>
{
if
(
res
.
code
===
200
)
{
this
.
$message
.
success
(
"上电操作成功"
);
this
.
closePowerOnDialog
();
}
else
{
this
.
$message
.
error
(
"上电操作失败"
);
}
}).
catch
(
err
=>
{
this
.
$message
.
error
(
"上电操作失败"
);
});
if
(
res
.
code
===
200
)
{
this
.
$message
.
success
(
"上电操作成功"
);
this
.
closePowerOnDialog
();
}
else
{
this
.
$message
.
error
(
"上电操作失败"
);
}
}).
catch
(
err
=>
{
this
.
$message
.
error
(
"上电操作失败"
);
});
},
// 切换优先级
togglePriority
()
{
this
.
priority
=
this
.
priority
===
'loading'
?
'unloading'
:
'loading'
;
updateInstructionExecutionPriority
(
this
.
priority
).
then
(
res
=>
{
if
(
res
.
code
===
200
)
{
this
.
$message
.
success
(
"优先级设置成功"
);
}
else
{
this
.
$message
.
error
(
"优先级设置失败"
);
}
if
(
res
.
code
===
200
)
{
this
.
$message
.
success
(
"优先级设置成功"
);
}
else
{
this
.
$message
.
error
(
"优先级设置失败"
);
}
})
// 这里可以添加发送优先级设置到后端的逻辑
console
.
log
(
`优先级已切换为:
${
this
.
priorityDisplayText
}
: this.priority:
${
this
.
priority
}
`
);
},
// 消息提示方法
msgSuccess
(
msg
)
{
this
.
$message
.
success
(
msg
);
msgSuccess
(
msg
)
{
this
.
$message
.
success
(
msg
);
},
msgError
(
msg
)
{
this
.
$message
.
error
(
msg
);
},
// ==================== 新增:动画暂停/继续 ====================
toggleAnimation
()
{
const
action
=
this
.
isAnimating
?
'暂停'
:
'继续'
;
this
.
$confirm
(
`确定要
${
action
}
机械臂动作吗?`
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'info'
}).
then
(()
=>
{
// 用户点击确定:切换动画状态
this
.
isAnimating
=
!
this
.
isAnimating
;
const
actionStr
=
this
.
isAnimating
?
'start'
:
'stop'
;
updateAnimationState
(
actionStr
).
then
(()
=>
{
this
.
$message
.
success
(
`动画已
${
action
}
`
);
}).
catch
(()
=>
{
this
.
$message
.
error
(
`操作失败`
);
// 如果失败,可恢复状态
this
.
isAnimating
=
!
this
.
isAnimating
;
});
}).
catch
(()
=>
{
// 用户点击取消
this
.
$message
.
info
(
`已取消
${
action
}
操作`
);
});
},
msgError
(
msg
)
{
this
.
$message
.
error
(
msg
);
// ==================== 新增:断电失败修复对话框相关 ====================
closeFixDialog
()
{
this
.
showFixDialog
=
false
;
this
.
selectedFailedCommand
=
null
;
},
// 修复确认后的处理(您可在此完善具体逻辑)
handleFixConfirm
()
{
if
(
!
this
.
selectedFailedCommand
)
return
;
powerFailureResolved
(
this
.
selectedFailedCommand
.
robotArmCommandId
).
then
(
res
=>
{
if
(
res
.
code
===
200
)
{
this
.
$message
.
success
(
"断电修复成功"
);
}
else
{
this
.
$message
.
error
(
"断电修复失败"
);
}
})
this
.
$message
.
success
(
'修复操作已执行(待完善)'
);
this
.
closeFixDialog
();
}
}
};
</
script
>
<
style
scoped
>
/* 新增:暂停动画类,作用于所有动画元素 */
.paused-animation
.robotic-arm
*
{
animation-play-state
:
paused
!important
;
}
/* 标题区域样式 */
.panel-title
{
position
:
absolute
;
...
...
@@ -1505,6 +1380,13 @@ export default {
border
:
1px
solid
rgba
(
180
,
180
,
180
,
0.5
);
}
.command-item.status-5
{
/* 断电失败 */
background
:
rgba
(
80
,
0
,
0
,
0.3
);
border
:
1px
solid
rgb
(
208
,
24
,
24
);
cursor
:
pointer
;
animation
:
blink-red
1s
infinite
;
/* 保持原未上电动画 */
}
/* 状态文本颜色 */
.status-0
.cmd-status
{
color
:
#a0a0ff
;
/* 待分配位置文本色 */
...
...
@@ -1526,6 +1408,9 @@ export default {
color
:
#a0a0a0
;
/* 执行结束文本色 */
}
.status-5
.cmd-status
{
color
:
#d01818
;
/* 未上电文本色 */
}
/* 状态文本样式 */
.cmd-status
{
font-size
:
12px
;
...
...
zhmes-agecal-web/src/views/screen/components/RoboticArm.vue
→
zhmes-agecal-web/src/views/screen/components/RoboticArm
-nouse
.vue
View file @
4198ca5c
File moved
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