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
debf3249
Commit
debf3249
authored
Nov 22, 2025
by
wanghao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1 时间校准 和 实时AD 处理 流程功能开发。
2 实时AD 范围值 界面维护功能开发。 3 上传MES 地址 界面维护功能实现。
parent
ee9a8ec3
Show whitespace changes
Inline
Side-by-side
Showing
33 changed files
with
2395 additions
and
72 deletions
+2395
-72
SysRealTimeAdRangeController.java
...eb/controller/equipment/SysRealTimeAdRangeController.java
+92
-0
TStoreyInfoController.java
...ehong/web/controller/equipment/TStoreyInfoController.java
+8
-0
SysConfigController.java
...com/zehong/web/controller/system/SysConfigController.java
+19
-0
MesDeviceDomain.java
...c/main/java/com/zehong/system/domain/MesDeviceDomain.java
+114
-0
PalletDeviceBinding.java
...in/java/com/zehong/system/domain/PalletDeviceBinding.java
+68
-2
SysRealTimeAdRange.java
...ain/java/com/zehong/system/domain/SysRealTimeAdRange.java
+65
-0
PalletDeviceBindingMapper.java
...a/com/zehong/system/mapper/PalletDeviceBindingMapper.java
+4
-0
SysConfigMapper.java
...c/main/java/com/zehong/system/mapper/SysConfigMapper.java
+2
-0
SysRealTimeAdRangeMapper.java
...va/com/zehong/system/mapper/SysRealTimeAdRangeMapper.java
+63
-0
NettyUdpServerHandler.java
...om/zehong/system/netty/handler/NettyUdpServerHandler.java
+90
-6
IPalletDeviceBindingService.java
...om/zehong/system/service/IPalletDeviceBindingService.java
+4
-0
ISysConfigService.java
...ain/java/com/zehong/system/service/ISysConfigService.java
+4
-0
ISysRealTimeAdRangeService.java
...com/zehong/system/service/ISysRealTimeAdRangeService.java
+65
-0
ITStoreyInfoService.java
...n/java/com/zehong/system/service/ITStoreyInfoService.java
+2
-0
PalletDeviceBindingServiceImpl.java
...g/system/service/impl/PalletDeviceBindingServiceImpl.java
+16
-0
SysConfigServiceImpl.java
.../com/zehong/system/service/impl/SysConfigServiceImpl.java
+36
-3
SysRealTimeAdRangeServiceImpl.java
...ng/system/service/impl/SysRealTimeAdRangeServiceImpl.java
+101
-0
TStoreyInfoServiceImpl.java
...om/zehong/system/service/impl/TStoreyInfoServiceImpl.java
+72
-10
DeviceCommunicationJob.java
...n/java/com/zehong/system/task/DeviceCommunicationJob.java
+5
-5
DeviceTaskScheduler.java
...main/java/com/zehong/system/task/DeviceTaskScheduler.java
+44
-4
PrepareFinalExecutionJob.java
...java/com/zehong/system/task/PrepareFinalExecutionJob.java
+630
-0
PalletDeviceBindingMapper.xml
...ain/resources/mapper/system/PalletDeviceBindingMapper.xml
+65
-6
SysConfigMapper.xml
...stem/src/main/resources/mapper/system/SysConfigMapper.xml
+3
-0
SysRealTimeAdRangeMapper.xml
...main/resources/mapper/system/SysRealTimeAdRangeMapper.xml
+65
-0
TStoreyInfoMapper.xml
...em/src/main/resources/mapper/system/TStoreyInfoMapper.xml
+1
-0
realAdRange.js
zhmes-agecal-web/src/api/realAdRange/realAdRange.js
+59
-0
storey.js
zhmes-agecal-web/src/api/storey/storey.js
+10
-2
config.js
zhmes-agecal-web/src/api/system/config.js
+15
-1
index.vue
zhmes-agecal-web/src/views/realAdRange/index.vue
+170
-0
oldIndex.vue
zhmes-agecal-web/src/views/realAdRange/oldIndex.vue
+285
-0
RealTimeData.vue
...s-agecal-web/src/views/screen/components/RealTimeData.vue
+41
-17
index.vue
zhmes-agecal-web/src/views/storey/index.vue
+36
-16
index.vue
zhmes-agecal-web/src/views/uploadMesAddress/index.vue
+141
-0
No files found.
zhmes-agecal-admin/src/main/java/com/zehong/web/controller/equipment/SysRealTimeAdRangeController.java
0 → 100644
View file @
debf3249
package
com
.
zehong
.
web
.
controller
.
equipment
;
import
com.zehong.common.core.controller.BaseController
;
import
com.zehong.common.core.domain.AjaxResult
;
import
com.zehong.common.core.page.TableDataInfo
;
import
com.zehong.common.utils.poi.ExcelUtil
;
import
com.zehong.system.domain.SysRealTimeAdRange
;
import
com.zehong.system.service.ISysRealTimeAdRangeService
;
import
org.springframework.web.bind.annotation.*
;
import
javax.annotation.Resource
;
import
java.util.List
;
/**
* 实时AD范围维护Controller
*
* @author zehong
* @date 2025-11-22
*/
@RestController
@RequestMapping
(
"/system/realAdRange"
)
public
class
SysRealTimeAdRangeController
extends
BaseController
{
@Resource
private
ISysRealTimeAdRangeService
sysRealTimeAdRangeService
;
/**
* 查询实时AD范围维护列表
*/
@GetMapping
(
"/list"
)
public
TableDataInfo
list
(
SysRealTimeAdRange
sysRealTimeAdRange
)
{
startPage
();
List
<
SysRealTimeAdRange
>
list
=
sysRealTimeAdRangeService
.
selectSysRealTimeAdRangeList
(
sysRealTimeAdRange
);
return
getDataTable
(
list
);
}
/**
* 获取实时AD范围维护列表
*/
@GetMapping
(
"/getTopOne"
)
public
AjaxResult
getTopOne
()
{
return
sysRealTimeAdRangeService
.
getTopOne
();
}
/**
* 导出实时AD范围维护列表
*/
@GetMapping
(
"/export"
)
public
AjaxResult
export
(
SysRealTimeAdRange
sysRealTimeAdRange
)
{
List
<
SysRealTimeAdRange
>
list
=
sysRealTimeAdRangeService
.
selectSysRealTimeAdRangeList
(
sysRealTimeAdRange
);
ExcelUtil
<
SysRealTimeAdRange
>
util
=
new
ExcelUtil
<
SysRealTimeAdRange
>(
SysRealTimeAdRange
.
class
);
return
util
.
exportExcel
(
list
,
"实时AD范围维护数据"
);
}
/**
* 获取实时AD范围维护详细信息
*/
@GetMapping
(
value
=
"/{id}"
)
public
AjaxResult
getInfo
(
@PathVariable
(
"id"
)
Long
id
)
{
return
AjaxResult
.
success
(
sysRealTimeAdRangeService
.
selectSysRealTimeAdRangeById
(
id
));
}
/**
* 新增实时AD范围维护
*/
@PostMapping
public
AjaxResult
add
(
@RequestBody
SysRealTimeAdRange
sysRealTimeAdRange
)
{
return
AjaxResult
.
success
(
sysRealTimeAdRangeService
.
insertSysRealTimeAdRange
(
sysRealTimeAdRange
));
}
/**
* 修改实时AD范围维护
*/
@PutMapping
public
AjaxResult
edit
(
@RequestBody
SysRealTimeAdRange
sysRealTimeAdRange
)
{
return
toAjax
(
sysRealTimeAdRangeService
.
updateSysRealTimeAdRange
(
sysRealTimeAdRange
));
}
/**
* 删除实时AD范围维护
*/
@DeleteMapping
(
"/{ids}"
)
public
AjaxResult
remove
(
@PathVariable
Long
[]
ids
)
{
return
toAjax
(
sysRealTimeAdRangeService
.
deleteSysRealTimeAdRangeByIds
(
ids
));
}
}
zhmes-agecal-admin/src/main/java/com/zehong/web/controller/equipment/TStoreyInfoController.java
View file @
debf3249
...
...
@@ -96,6 +96,14 @@ public class TStoreyInfoController extends BaseController
return
tStoreyInfoService
.
handleBlanking
(
command
);
}
/**
* 处理再老化
*/
@GetMapping
(
value
=
"/handleReAgine"
)
public
AjaxResult
handleReAgine
(
TStoreyInfo
tStoreyInfo
)
{
return
tStoreyInfoService
.
handleReAgine
(
tStoreyInfo
);
}
/**
* 处理直接消 blanking
*/
...
...
zhmes-agecal-admin/src/main/java/com/zehong/web/controller/system/SysConfigController.java
View file @
debf3249
package
com
.
zehong
.
web
.
controller
.
system
;
import
java.util.List
;
import
com.zehong.system.netty.handler.NettyUdpServerHandler
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.validation.annotation.Validated
;
...
...
@@ -77,6 +79,23 @@ public class SysConfigController extends BaseController
return
AjaxResult
.
success
(
configService
.
selectConfigByKey
(
configKey
));
}
/**
* 获取上传mes地址
*/
@GetMapping
(
value
=
"/getUploadMesAddress"
)
public
AjaxResult
getUploadMesAddress
()
{
return
AjaxResult
.
success
(
configService
.
directSelectConfigByKey
(
NettyUdpServerHandler
.
UPLOAD_MES_ADDRESS
));
}
/**
* 修改上传mes地址
*/
@PostMapping
(
value
=
"/updateUploadMesAddress"
)
public
AjaxResult
updateUploadMesAddress
(
@RequestBody
SysConfig
config
)
{
return
toAjax
(
configService
.
updateUploadMesAddress
(
config
));
}
/**
* 新增参数配置
*/
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/domain/MesDeviceDomain.java
0 → 100644
View file @
debf3249
package
com
.
zehong
.
system
.
domain
;
import
com.zehong.common.core.domain.BaseEntity
;
/**
* @author lenovo
* @date 2025/11/22
* @description MES设备对象
*/
public
class
MesDeviceDomain
extends
BaseEntity
{
private
static
final
long
serialVersionUID
=
1L
;
/** 主板码 */
private
String
motherboardCode
;
/**
* 零点AD值
*/
private
String
zeroAdValue
;
/**
*零点状态 0-未校准 1-已校准
*/
private
String
zeroStatus
;
/**
* 校准AD值
*/
private
String
calibratedAdValue
;
/**
* 校准状态
*/
private
String
calibrationStatus
;
/**
* 浓度
*/
private
String
concentration
;
/**
* 实时AD
*/
private
Integer
realTimeAd
;
/**
* 实时状态 0-异常;1-正常
*/
private
String
realTimeStatus
;
public
String
getMotherboardCode
()
{
return
motherboardCode
;
}
public
void
setMotherboardCode
(
String
motherboardCode
)
{
this
.
motherboardCode
=
motherboardCode
;
}
public
String
getZeroAdValue
()
{
return
zeroAdValue
;
}
public
void
setZeroAdValue
(
String
zeroAdValue
)
{
this
.
zeroAdValue
=
zeroAdValue
;
}
public
String
getZeroStatus
()
{
return
zeroStatus
;
}
public
void
setZeroStatus
(
String
zeroStatus
)
{
this
.
zeroStatus
=
zeroStatus
;
}
public
String
getCalibratedAdValue
()
{
return
calibratedAdValue
;
}
public
void
setCalibratedAdValue
(
String
calibratedAdValue
)
{
this
.
calibratedAdValue
=
calibratedAdValue
;
}
public
String
getCalibrationStatus
()
{
return
calibrationStatus
;
}
public
void
setCalibrationStatus
(
String
calibrationStatus
)
{
this
.
calibrationStatus
=
calibrationStatus
;
}
public
String
getConcentration
()
{
return
concentration
;
}
public
void
setConcentration
(
String
concentration
)
{
this
.
concentration
=
concentration
;
}
public
Integer
getRealTimeAd
()
{
return
realTimeAd
;
}
public
void
setRealTimeAd
(
Integer
realTimeAd
)
{
this
.
realTimeAd
=
realTimeAd
;
}
public
String
getRealTimeStatus
()
{
return
realTimeStatus
;
}
public
void
setRealTimeStatus
(
String
realTimeStatus
)
{
this
.
realTimeStatus
=
realTimeStatus
;
}
}
zhmes-agecal-system/src/main/java/com/zehong/system/domain/PalletDeviceBinding.java
View file @
debf3249
...
...
@@ -95,20 +95,46 @@ public class PalletDeviceBinding extends BaseEntity
private
String
writeTimeStatus
;
/**
* 零点
校准
AD
* 零点AD
*/
private
String
adjustmentZeroAd
;
/**
* 零点校准AD
* 零点状态 0-异常;1-正常
*/
private
String
zeroStatus
;
/**
* 校准AD
*/
private
String
calibrationAd
;
/**
* 零点状态 0-异常;1-正常
*/
private
String
calibrationAdStatus
;
/**
* 浓度
*/
private
String
concentration
;
/**
* 运行时间状态 0-失败;1-成功
*/
private
String
runTimeStatus
;
/**
* 实时AD
*/
private
Integer
realTimeAd
;
/**
* 实时状态 0-异常;1-正常
*/
private
String
realTimeStatus
;
public
String
getStatus
()
{
return
status
;
}
...
...
@@ -277,6 +303,46 @@ public class PalletDeviceBinding extends BaseEntity
this
.
number
=
number
;
}
public
String
getRunTimeStatus
()
{
return
runTimeStatus
;
}
public
void
setRunTimeStatus
(
String
runTimeStatus
)
{
this
.
runTimeStatus
=
runTimeStatus
;
}
public
Integer
getRealTimeAd
()
{
return
realTimeAd
;
}
public
void
setRealTimeAd
(
Integer
realTimeAd
)
{
this
.
realTimeAd
=
realTimeAd
;
}
public
String
getRealTimeStatus
()
{
return
realTimeStatus
;
}
public
void
setRealTimeStatus
(
String
realTimeStatus
)
{
this
.
realTimeStatus
=
realTimeStatus
;
}
public
String
getZeroStatus
()
{
return
zeroStatus
;
}
public
void
setZeroStatus
(
String
zeroStatus
)
{
this
.
zeroStatus
=
zeroStatus
;
}
public
String
getCalibrationAdStatus
()
{
return
calibrationAdStatus
;
}
public
void
setCalibrationAdStatus
(
String
calibrationAdStatus
)
{
this
.
calibrationAdStatus
=
calibrationAdStatus
;
}
@Override
public
String
toString
()
{
return
new
ToStringBuilder
(
this
,
ToStringStyle
.
MULTI_LINE_STYLE
)
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/domain/SysRealTimeAdRange.java
0 → 100644
View file @
debf3249
package
com
.
zehong
.
system
.
domain
;
import
org.apache.commons.lang3.builder.ToStringBuilder
;
import
org.apache.commons.lang3.builder.ToStringStyle
;
import
com.zehong.common.annotation.Excel
;
import
com.zehong.common.core.domain.BaseEntity
;
/**
* 实时AD范围维护对象 t_sys_real_time_ad_range
*
* @author zehong
* @date 2025-11-22
*/
public
class
SysRealTimeAdRange
extends
BaseEntity
{
private
static
final
long
serialVersionUID
=
1L
;
/** 主键ID */
private
Long
id
;
/** 实时AD最小值 */
@Excel
(
name
=
"实时AD最小值"
)
private
Long
realTimeAdMin
;
/** 实时AD最大值 */
@Excel
(
name
=
"实时AD最大值"
)
private
Long
realTimeAdMax
;
public
void
setId
(
Long
id
)
{
this
.
id
=
id
;
}
public
Long
getId
()
{
return
id
;
}
public
void
setRealTimeAdMin
(
Long
realTimeAdMin
)
{
this
.
realTimeAdMin
=
realTimeAdMin
;
}
public
Long
getRealTimeAdMin
()
{
return
realTimeAdMin
;
}
public
void
setRealTimeAdMax
(
Long
realTimeAdMax
)
{
this
.
realTimeAdMax
=
realTimeAdMax
;
}
public
Long
getRealTimeAdMax
()
{
return
realTimeAdMax
;
}
@Override
public
String
toString
()
{
return
new
ToStringBuilder
(
this
,
ToStringStyle
.
MULTI_LINE_STYLE
)
.
append
(
"id"
,
getId
())
.
append
(
"realTimeAdMin"
,
getRealTimeAdMin
())
.
append
(
"realTimeAdMax"
,
getRealTimeAdMax
())
.
toString
();
}
}
zhmes-agecal-system/src/main/java/com/zehong/system/mapper/PalletDeviceBindingMapper.java
View file @
debf3249
...
...
@@ -38,6 +38,8 @@ public interface PalletDeviceBindingMapper
public
List
<
PalletDeviceBinding
>
getAllExcludeUnbindingTimeByTrayId
(
Long
trayId
);
public
List
<
PalletDeviceBinding
>
listByTrayCode
(
String
trayCode
);
public
int
countErrorByTrayId
(
Long
trayId
);
public
int
countByTrayId
(
Long
trayId
);
...
...
@@ -70,6 +72,8 @@ public interface PalletDeviceBindingMapper
public
int
batchUpdateDeviceCode
(
@Param
(
"palletDeviceBindingList"
)
List
<
PalletDeviceBinding
>
palletDeviceBindingList
);
public
int
batchUpdateAdAndStatus
(
@Param
(
"palletDeviceBindingList"
)
List
<
PalletDeviceBinding
>
palletDeviceBindingList
);
public
int
batchUpdateDeviceCodeAndUnbindingTime
(
@Param
(
"palletDeviceBindingList"
)
List
<
PalletDeviceBinding
>
palletDeviceBindingList
);
public
int
unbindAllDevice
(
Long
trayId
);
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/mapper/SysConfigMapper.java
View file @
debf3249
...
...
@@ -50,6 +50,8 @@ public interface SysConfigMapper
*/
public
int
updateConfig
(
SysConfig
config
);
public
int
directUpdateConfigByKey
(
SysConfig
config
);
/**
* 删除参数配置
*
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/mapper/SysRealTimeAdRangeMapper.java
0 → 100644
View file @
debf3249
package
com
.
zehong
.
system
.
mapper
;
import
java.util.List
;
import
com.zehong.system.domain.SysRealTimeAdRange
;
/**
* 实时AD范围维护Mapper接口
*
* @author zehong
* @date 2025-11-22
*/
public
interface
SysRealTimeAdRangeMapper
{
/**
* 查询实时AD范围维护
*
* @param id 实时AD范围维护ID
* @return 实时AD范围维护
*/
public
SysRealTimeAdRange
selectSysRealTimeAdRangeById
(
Long
id
);
/**
* 查询实时AD范围维护列表
*
* @param sysRealTimeAdRange 实时AD范围维护
* @return 实时AD范围维护集合
*/
public
List
<
SysRealTimeAdRange
>
selectSysRealTimeAdRangeList
(
SysRealTimeAdRange
sysRealTimeAdRange
);
public
SysRealTimeAdRange
getTopOne
();
/**
* 新增实时AD范围维护
*
* @param sysRealTimeAdRange 实时AD范围维护
* @return 结果
*/
public
int
insertSysRealTimeAdRange
(
SysRealTimeAdRange
sysRealTimeAdRange
);
/**
* 修改实时AD范围维护
*
* @param sysRealTimeAdRange 实时AD范围维护
* @return 结果
*/
public
int
updateSysRealTimeAdRange
(
SysRealTimeAdRange
sysRealTimeAdRange
);
/**
* 删除实时AD范围维护
*
* @param id 实时AD范围维护ID
* @return 结果
*/
public
int
deleteSysRealTimeAdRangeById
(
Long
id
);
/**
* 批量删除实时AD范围维护
*
* @param ids 需要删除的数据ID
* @return 结果
*/
public
int
deleteSysRealTimeAdRangeByIds
(
Long
[]
ids
);
}
zhmes-agecal-system/src/main/java/com/zehong/system/netty/handler/NettyUdpServerHandler.java
View file @
debf3249
package
com
.
zehong
.
system
.
netty
.
handler
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.zehong.common.utils.StringUtils
;
import
com.zehong.common.utils.http.HttpUtils
;
import
com.zehong.system.domain.MesDeviceDomain
;
import
com.zehong.system.domain.PalletDeviceBinding
;
import
com.zehong.system.domain.RobotArmCommand
;
import
com.zehong.system.service.IPalletDeviceBindingService
;
import
com.zehong.system.service.IRobotArmCommandService
;
import
com.zehong.system.service.ISysConfigService
;
import
com.zehong.system.service.websocket.RobotArmWebSocketHandler
;
import
com.zehong.system.udp.RobotArmMessageParser
;
import
io.netty.buffer.ByteBuf
;
...
...
@@ -19,14 +27,12 @@ import javax.annotation.Resource;
import
java.net.SocketAddress
;
import
java.nio.charset.StandardCharsets
;
import
java.text.SimpleDateFormat
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.*
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.locks.ReentrantLock
;
import
java.io.*
;
import
java.util.Date
;
/**
* @author lenovo
* @date 2025/7/31
...
...
@@ -40,6 +46,9 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
// 日志文件保存目录
// 写法1:使用双反斜杠
private
static
final
String
LOG_DIR
=
"D:\\BaiduNetdiskDownload\\udp_message_logs\\"
;
// 上传MES地址的key
public
static
final
String
UPLOAD_MES_ADDRESS
=
"uploadMesAddress"
;
// 日期格式器,用于生成文件名和日志时间
private
static
final
SimpleDateFormat
DATE_FORMATTER
=
new
SimpleDateFormat
(
"yyyyMMdd"
);
private
static
final
SimpleDateFormat
TIME_FORMATTER
=
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
);
...
...
@@ -58,6 +67,12 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
@Resource
private
IRobotArmCommandService
robotArmCommandService
;
@Resource
private
IPalletDeviceBindingService
palletDeviceBindingService
;
@Resource
private
ISysConfigService
sysConfigService
;
/**
* 接收UDP消息
*/
...
...
@@ -161,7 +176,6 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
* 处理校准消息
*/
private
void
handleCalibrationMessage
(
ChannelHandlerContext
ctx
,
DatagramPacket
packet
,
String
message
)
{
// TODO: 实现校准消息的具体处理逻辑
log
.
info
(
"收到校准消息: {}"
,
message
);
// 示例:解析校准数据
...
...
@@ -174,9 +188,79 @@ public class NettyUdpServerHandler extends SimpleChannelInboundHandler<DatagramP
io
.
netty
.
buffer
.
Unpooled
.
copiedBuffer
(
responseBytes
),
packet
.
sender
()));
// TODO: 添加具体的校准业务逻辑
// 例如:更新校准状态、保存校准数据、通知前端等
// 1 根据信息拿到点位信息 假如说1L是传过来的
List
<
PalletDeviceBinding
>
palletDeviceBindings
=
initAdAndStatus
(
message
);
// 2 解析数据上传MES 返回是否成功
Boolean
aBoolean
=
initMesDataAndUpload
(
palletDeviceBindings
);
// 3 三次失败后 记录到本系统,之后有时间再手动上传
if
(!
aBoolean
)
{
}
}
/**
* 初始化MES数据并上传
*/
private
Boolean
initMesDataAndUpload
(
List
<
PalletDeviceBinding
>
palletDeviceBindings
)
{
List
<
MesDeviceDomain
>
mesDeviceDomains
=
new
ArrayList
<>();
for
(
PalletDeviceBinding
palletDeviceBinding
:
palletDeviceBindings
)
{
MesDeviceDomain
mesDeviceDomain
=
new
MesDeviceDomain
();
// 主板码
mesDeviceDomain
.
setMotherboardCode
(
palletDeviceBinding
.
getDeviceCode
());
// 零点AD
mesDeviceDomain
.
setZeroAdValue
(
palletDeviceBinding
.
getAdjustmentZeroAd
());
// 零点AD状态
mesDeviceDomain
.
setZeroStatus
(
palletDeviceBinding
.
getZeroStatus
());
// 标定AD
mesDeviceDomain
.
setCalibratedAdValue
(
palletDeviceBinding
.
getCalibrationAd
());
// 标定AD状态
mesDeviceDomain
.
setCalibrationStatus
(
palletDeviceBinding
.
getCalibrationAdStatus
());
// 浓度
mesDeviceDomain
.
setConcentration
(
palletDeviceBinding
.
getConcentration
());
// 实时AD
mesDeviceDomain
.
setRealTimeAd
(
palletDeviceBinding
.
getRealTimeAd
());
// 实时状态
mesDeviceDomain
.
setRealTimeStatus
(
palletDeviceBinding
.
getRealTimeStatus
());
mesDeviceDomains
.
add
(
mesDeviceDomain
);
}
String
mesUploadAddress
=
sysConfigService
.
directSelectConfigByKey
(
UPLOAD_MES_ADDRESS
);
if
(
StringUtils
.
isNotBlank
(
mesUploadAddress
))
{
String
result
=
HttpUtils
.
sendPost
(
mesUploadAddress
,
JSON
.
toJSONString
(
mesDeviceDomains
));
if
(
StringUtils
.
isBlank
(
result
))
{
return
false
;
}
JSONObject
jsonObject
=
JSON
.
parseObject
(
result
);
if
(
jsonObject
.
getInteger
(
"code"
)
==
200
)
{
return
true
;
}
}
return
false
;
}
/**
* 根据托盘码查询托盘绑定的设备列
*/
private
List
<
PalletDeviceBinding
>
initAdAndStatus
(
String
message
)
{
List
<
PalletDeviceBinding
>
palletDeviceBindings
=
palletDeviceBindingService
.
listByTrayCode
(
"1L"
);
// 根据message 处理 零点AD 零点AD状态 标定AD 标定AD状态
// 批量更新
palletDeviceBindingService
.
batchUpdateAdAndStatus
(
palletDeviceBindings
);
return
palletDeviceBindings
;
}
/**
* 仅处理已完成的指令
*/
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/service/IPalletDeviceBindingService.java
View file @
debf3249
...
...
@@ -31,6 +31,10 @@ public interface IPalletDeviceBindingService
public
List
<
PalletDeviceBinding
>
getAllExcludeUnbindingTimeByTrayId
(
Long
trayId
);
public
List
<
PalletDeviceBinding
>
listByTrayCode
(
String
trayCode
);
public
void
batchUpdateAdAndStatus
(
List
<
PalletDeviceBinding
>
palletDeviceBindingList
);
/**
* 新增托盘绑定的设备列
*
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/service/ISysConfigService.java
View file @
debf3249
...
...
@@ -26,6 +26,8 @@ public interface ISysConfigService
*/
public
String
selectConfigByKey
(
String
configKey
);
public
String
directSelectConfigByKey
(
String
configKey
);
/**
* 查询参数配置列表
*
...
...
@@ -50,6 +52,8 @@ public interface ISysConfigService
*/
public
int
updateConfig
(
SysConfig
config
);
public
int
updateUploadMesAddress
(
SysConfig
sysConfig
);
/**
* 批量删除参数信息
*
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/service/ISysRealTimeAdRangeService.java
0 → 100644
View file @
debf3249
package
com
.
zehong
.
system
.
service
;
import
java.util.List
;
import
com.zehong.common.core.domain.AjaxResult
;
import
com.zehong.system.domain.SysRealTimeAdRange
;
/**
* 实时AD范围维护Service接口
*
* @author zehong
* @date 2025-11-22
*/
public
interface
ISysRealTimeAdRangeService
{
/**
* 查询实时AD范围维护
*
* @param id 实时AD范围维护ID
* @return 实时AD范围维护
*/
public
SysRealTimeAdRange
selectSysRealTimeAdRangeById
(
Long
id
);
/**
* 查询实时AD范围维护列表
*
* @param sysRealTimeAdRange 实时AD范围维护
* @return 实时AD范围维护集合
*/
public
List
<
SysRealTimeAdRange
>
selectSysRealTimeAdRangeList
(
SysRealTimeAdRange
sysRealTimeAdRange
);
public
AjaxResult
getTopOne
();
/**
* 新增实时AD范围维护
*
* @param sysRealTimeAdRange 实时AD范围维护
* @return 结果
*/
public
Long
insertSysRealTimeAdRange
(
SysRealTimeAdRange
sysRealTimeAdRange
);
/**
* 修改实时AD范围维护
*
* @param sysRealTimeAdRange 实时AD范围维护
* @return 结果
*/
public
int
updateSysRealTimeAdRange
(
SysRealTimeAdRange
sysRealTimeAdRange
);
/**
* 批量删除实时AD范围维护
*
* @param ids 需要删除的实时AD范围维护ID
* @return 结果
*/
public
int
deleteSysRealTimeAdRangeByIds
(
Long
[]
ids
);
/**
* 删除实时AD范围维护信息
*
* @param id 实时AD范围维护ID
* @return 结果
*/
public
int
deleteSysRealTimeAdRangeById
(
Long
id
);
}
zhmes-agecal-system/src/main/java/com/zehong/system/service/ITStoreyInfoService.java
View file @
debf3249
...
...
@@ -60,6 +60,8 @@ public interface ITStoreyInfoService
public
AjaxResult
handleBlanking
(
String
command
);
public
AjaxResult
handleReAgine
(
TStoreyInfo
tStoreyInfo
);
public
AjaxResult
handleDirectBlanking
(
String
command
);
/**
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/service/impl/PalletDeviceBindingServiceImpl.java
View file @
debf3249
...
...
@@ -65,6 +65,22 @@ public class PalletDeviceBindingServiceImpl implements IPalletDeviceBindingServi
return
palletDeviceBindingMapper
.
getAllExcludeUnbindingTimeByTrayId
(
trayId
);
}
/**
* 根据托盘码查询托盘绑定的设备列
*
* @param trayCode 托盘码
* @return 列表
*/
@Override
public
List
<
PalletDeviceBinding
>
listByTrayCode
(
String
trayCode
)
{
return
palletDeviceBindingMapper
.
listByTrayCode
(
trayCode
);
}
@Override
public
void
batchUpdateAdAndStatus
(
List
<
PalletDeviceBinding
>
palletDeviceBindingList
)
{
palletDeviceBindingMapper
.
batchUpdateAdAndStatus
(
palletDeviceBindingList
);
}
/**
* 新增托盘绑定的设备列
*
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/service/impl/SysConfigServiceImpl.java
View file @
debf3249
...
...
@@ -3,7 +3,9 @@ package com.zehong.system.service.impl;
import
java.util.Collection
;
import
java.util.List
;
import
javax.annotation.PostConstruct
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
javax.annotation.Resource
;
import
com.zehong.system.netty.handler.NettyUdpServerHandler
;
import
org.springframework.stereotype.Service
;
import
com.zehong.common.annotation.DataSource
;
import
com.zehong.common.constant.Constants
;
...
...
@@ -25,10 +27,10 @@ import com.zehong.system.service.ISysConfigService;
@Service
public
class
SysConfigServiceImpl
implements
ISysConfigService
{
@
Autowired
@
Resource
private
SysConfigMapper
configMapper
;
@
Autowired
@
Resource
private
RedisCache
redisCache
;
/**
...
...
@@ -80,6 +82,26 @@ public class SysConfigServiceImpl implements ISysConfigService
return
StringUtils
.
EMPTY
;
}
/**
* 根据键名查询参数配置信息-直接查询不经过redis
*
* @param configKey 键名
* @return 参数键值
*/
@Override
public
String
directSelectConfigByKey
(
String
configKey
)
{
if
(
StringUtils
.
isBlank
(
configKey
))
{
return
StringUtils
.
EMPTY
;
}
SysConfig
config
=
new
SysConfig
();
config
.
setConfigKey
(
configKey
);
SysConfig
sysConfig
=
configMapper
.
selectConfig
(
config
);
if
(
sysConfig
!=
null
)
{
return
sysConfig
.
getConfigValue
();
}
return
StringUtils
.
EMPTY
;
}
/**
* 查询参数配置列表
*
...
...
@@ -126,6 +148,17 @@ public class SysConfigServiceImpl implements ISysConfigService
return
row
;
}
/**
* 修改上传地址
*
* @return 结果
*/
@Override
public
int
updateUploadMesAddress
(
SysConfig
sysConfig
)
{
sysConfig
.
setConfigKey
(
NettyUdpServerHandler
.
UPLOAD_MES_ADDRESS
);
return
configMapper
.
directUpdateConfigByKey
(
sysConfig
);
}
/**
* 批量删除参数信息
*
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/service/impl/SysRealTimeAdRangeServiceImpl.java
0 → 100644
View file @
debf3249
package
com
.
zehong
.
system
.
service
.
impl
;
import
com.zehong.common.core.domain.AjaxResult
;
import
com.zehong.system.domain.SysRealTimeAdRange
;
import
com.zehong.system.mapper.SysRealTimeAdRangeMapper
;
import
com.zehong.system.service.ISysRealTimeAdRangeService
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
import
java.util.List
;
/**
* 实时AD范围维护Service业务层处理
*
* @author zehong
* @date 2025-11-22
*/
@Service
public
class
SysRealTimeAdRangeServiceImpl
implements
ISysRealTimeAdRangeService
{
@Resource
private
SysRealTimeAdRangeMapper
sysRealTimeAdRangeMapper
;
/**
* 查询实时AD范围维护
*
* @param id 实时AD范围维护ID
* @return 实时AD范围维护
*/
@Override
public
SysRealTimeAdRange
selectSysRealTimeAdRangeById
(
Long
id
)
{
return
sysRealTimeAdRangeMapper
.
selectSysRealTimeAdRangeById
(
id
);
}
/**
* 查询实时AD范围维护列表
*
* @param sysRealTimeAdRange 实时AD范围维护
* @return 实时AD范围维护
*/
@Override
public
List
<
SysRealTimeAdRange
>
selectSysRealTimeAdRangeList
(
SysRealTimeAdRange
sysRealTimeAdRange
)
{
return
sysRealTimeAdRangeMapper
.
selectSysRealTimeAdRangeList
(
sysRealTimeAdRange
);
}
@Override
public
AjaxResult
getTopOne
()
{
return
AjaxResult
.
success
(
sysRealTimeAdRangeMapper
.
getTopOne
());
}
/**
* 新增实时AD范围维护
*
* @param sysRealTimeAdRange 实时AD范围维护
* @return 结果
*/
@Override
public
Long
insertSysRealTimeAdRange
(
SysRealTimeAdRange
sysRealTimeAdRange
)
{
sysRealTimeAdRangeMapper
.
insertSysRealTimeAdRange
(
sysRealTimeAdRange
);
return
sysRealTimeAdRange
.
getId
();
}
/**
* 修改实时AD范围维护
*
* @param sysRealTimeAdRange 实时AD范围维护
* @return 结果
*/
@Override
public
int
updateSysRealTimeAdRange
(
SysRealTimeAdRange
sysRealTimeAdRange
)
{
return
sysRealTimeAdRangeMapper
.
updateSysRealTimeAdRange
(
sysRealTimeAdRange
);
}
/**
* 批量删除实时AD范围维护
*
* @param ids 需要删除的实时AD范围维护ID
* @return 结果
*/
@Override
public
int
deleteSysRealTimeAdRangeByIds
(
Long
[]
ids
)
{
return
sysRealTimeAdRangeMapper
.
deleteSysRealTimeAdRangeByIds
(
ids
);
}
/**
* 删除实时AD范围维护信息
*
* @param id 实时AD范围维护ID
* @return 结果
*/
@Override
public
int
deleteSysRealTimeAdRangeById
(
Long
id
)
{
return
sysRealTimeAdRangeMapper
.
deleteSysRealTimeAdRangeById
(
id
);
}
}
zhmes-agecal-system/src/main/java/com/zehong/system/service/impl/TStoreyInfoServiceImpl.java
View file @
debf3249
...
...
@@ -560,6 +560,39 @@ public class TStoreyInfoServiceImpl implements ITStoreyInfoService
return
AjaxResult
.
success
();
}
/**
* 重新老化
* @param tStoreyInfo c
* @return r
*/
@Override
public
AjaxResult
handleReAgine
(
TStoreyInfo
tStoreyInfo
)
{
// CheckPowerOnCommandEvent 方法里面 会 重新开始记录老化时间
String
storeyCode
=
tStoreyInfo
.
getfStoreyCode
();
String
[]
parts
=
storeyCode
.
split
(
"-"
);
String
equitmentCode
=
parts
[
0
];
int
registerOffset
=
Integer
.
parseInt
(
parts
[
1
]);
TEquipmentInfo
tEquipmentInfo
=
equipmentInfoMapper
.
selectTEquipmentInfoByCode
(
equitmentCode
);
if
(
tEquipmentInfo
==
null
)
{
return
AjaxResult
.
error
(
"无此设备信息!!!"
);
}
String
powerOutageIp
=
tEquipmentInfo
.
getfPowerOutageIp
();
Integer
powerOutagePort
=
tEquipmentInfo
.
getfPowerOutagePort
();
eventPublisher
.
publishEvent
(
new
CheckPowerOnCommandEvent
(
this
,
equitmentCode
,
powerOutageIp
,
powerOutagePort
,
registerOffset
,
registerOffset
-
1
));
return
AjaxResult
.
success
();
}
/**
* 发送下料指令
* @return r
...
...
@@ -573,10 +606,13 @@ public class TStoreyInfoServiceImpl implements ITStoreyInfoService
if
(
notCompletedCommand
>
0
)
{
return
AjaxResult
.
error
(
"有未完成指令,请稍后再试"
);
}
else
{
// 根据指令 去查 老化层
TStoreyInfo
tStoreyInfo
=
tStoreyInfoMapper
.
selectByBlankingCommand
(
command
);
if
(
tStoreyInfo
==
null
)
{
return
AjaxResult
.
error
(
"无此指令对应的老化层信息"
);
}
if
(
checkStoreyInfoPower
(
tStoreyInfo
))
{
TTrayInfo
tTrayInfo
=
tTrayInfoMapper
.
selectTTrayInfoByStoreyCode
(
tStoreyInfo
.
getfStoreyCode
());
//还得去把没执行的 定时任务删掉,否则会导致 再次 发送下料指令
...
...
@@ -589,10 +625,36 @@ public class TStoreyInfoServiceImpl implements ITStoreyInfoService
if
(
tTrayInfo
!=
null
)
{
robotArmCommandService
.
generateBlankingCommand
(
tTrayInfo
.
getfTrayCode
(),
tStoreyInfo
.
getfStoreyCode
(),
command
);
}
}
else
{
robotArmCommandService
.
sendCommand
(
command
);
}
}
return
AjaxResult
.
success
();
}
/**
* 批量处理
* @param tStoreyInfo c
* @return r
*/
private
Boolean
checkStoreyInfoPower
(
TStoreyInfo
tStoreyInfo
)
{
TEquipmentInfo
tEquipmentInfo
=
equipmentInfoMapper
.
selectTEquipmentInfoById
(
tStoreyInfo
.
getfEquipmentId
());
String
registerOffset
=
tStoreyInfo
.
getfStoreyCode
().
split
(
"-"
)[
1
];
try
{
ModbusMaster
master
=
Modbus4jUtils
.
getMaster
(
tEquipmentInfo
.
getfPowerOutageIp
(),
tEquipmentInfo
.
getfPowerOutagePort
());
int
i
=
Integer
.
parseInt
(
registerOffset
);
int
registerOffsetInt
=
i
-
1
;
return
Modbus4jUtils
.
readCoilStatus
(
master
,
1
,
registerOffsetInt
);
}
catch
(
ModbusInitException
|
ModbusTransportException
|
ErrorResponseException
e
)
{
throw
new
RuntimeException
(
e
);
}
}
/**
* 批量开灯
* @return r
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/task/DeviceCommunicationJob.java
View file @
debf3249
...
...
@@ -15,19 +15,20 @@ import com.zehong.system.domain.TStoreyInfo;
import
com.zehong.system.mapper.PalletDeviceBindingMapper
;
import
com.zehong.system.mapper.TStoreyInfoMapper
;
import
com.zehong.system.modbus.handler.ModbusResultHandler
;
import
com.zehong.system.modbus.handler.dto.DeviceStatusReaderDto
;
import
com.zehong.system.modbus.util.Modbus4jUtils
;
import
com.zehong.system.service.ITEquipmentAlarmDataService
;
import
org.apache.commons.lang3.StringUtils
;
import
org.quartz.*
;
import
org.quartz.DisallowConcurrentExecution
;
import
org.quartz.Job
;
import
org.quartz.JobDataMap
;
import
org.quartz.JobExecutionContext
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
java.util.Calendar
;
import
javax.annotation.Resource
;
import
java.util.Arrays
;
import
java.util.Calendar
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.concurrent.*
;
...
...
@@ -45,7 +46,6 @@ public class DeviceCommunicationJob implements Job {
// -------------------------- 常量配置(统一管理,避免魔法值)--------------------------
// 超时控制:必须小于Cron周期(假设Cron为5分钟,这里留1分钟缓冲)
private
static
final
int
TOTAL_TASK_TIMEOUT_SEC
=
240
;
// 任务总超时:4分钟
private
static
final
int
SINGLE_PORT_TIMEOUT_SEC
=
60
;
// 单个端口超时:1分钟
private
static
final
int
SINGLE_DEVICE_TIMEOUT_SEC
=
10
;
// 单个设备超时:10秒
// Modbus配置:取消内置重试,统一用自定义重试
private
static
final
int
MODBUS_CONN_TIMEOUT_MS
=
3000
;
// 连接超时:3秒
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/task/DeviceTaskScheduler.java
View file @
debf3249
...
...
@@ -64,12 +64,13 @@ public class DeviceTaskScheduler {
// 2. 清理可能的残留任务
cleanExistingTasks
(
fStoreyId
);
// 3. 创建核心任务
// 1. 创建3个端口专属任务(501:5分钟后,502:10分钟后,503:15分钟后)
// createPortSpecificCommJobs(fStoreyId);
// 3. 创建5分钟开始读写时间的job
createHourlyCommunicationJob
(
fStoreyId
);
// 4. 创建71小时 执行的任务
prepareFinalExecutionJob
(
fStoreyId
);
// 5. 创建72小时 最终任务
createFinalExecutionJob
(
fStoreyId
,
fPowerOutageIp
,
fPowerOutagePort
);
checkTaskStatus
(
fStoreyId
);
...
...
@@ -262,6 +263,45 @@ public class DeviceTaskScheduler {
log
.
info
(
"通信任务[{}]创建成功,下次执行:{}"
,
jobId
,
nextFireTime
);
}
/**
* 创建71 小时 执行的任务逻辑
*/
private
void
prepareFinalExecutionJob
(
Long
fStoreyId
)
throws
SchedulerException
{
String
jobId
=
"PREPARE_"
+
fStoreyId
;
JobKey
jobKey
=
new
JobKey
(
jobId
,
JOB_GROUP
);
TriggerKey
triggerKey
=
new
TriggerKey
(
jobId
+
"_TRIGGER"
,
TRIGGER_GROUP
);
// 先删除旧的触发器和任务(彻底清理)
if
(
scheduler
.
checkExists
(
triggerKey
))
{
scheduler
.
unscheduleJob
(
triggerKey
);
}
if
(
scheduler
.
checkExists
(
jobKey
))
{
scheduler
.
deleteJob
(
jobKey
);
}
JobDetail
job
=
JobBuilder
.
newJob
(
PrepareFinalExecutionJob
.
class
)
.
withIdentity
(
jobKey
)
.
usingJobData
(
"fStoreyId"
,
fStoreyId
.
toString
())
.
storeDurably
(
false
)
.
build
();
Date
executeTime
=
Date
.
from
(
Instant
.
now
().
plus
(
10
,
ChronoUnit
.
MINUTES
));
// 关键修复:使用StartAt而不是StartNow
SimpleTrigger
trigger
=
TriggerBuilder
.
newTrigger
()
.
withIdentity
(
triggerKey
)
.
forJob
(
jobKey
)
.
withDescription
(
"设备"
+
fStoreyId
+
"最终任务触发器,触发时间是:"
+
executeTime
)
.
startAt
(
executeTime
)
.
withSchedule
(
SimpleScheduleBuilder
.
simpleSchedule
()
.
withMisfireHandlingInstructionFireNow
()
// 错过立即执行
.
withRepeatCount
(
0
))
// 仅一次
.
build
();
Date
nextFireTime
=
scheduler
.
scheduleJob
(
job
,
trigger
);
log
.
info
(
"通信任务[{}]创建成功,下次执行:{}"
,
jobId
,
nextFireTime
);
}
/**
* 2. 创建15分钟后执行的最终任务(保持原逻辑,优化超时)
*/
...
...
@@ -280,7 +320,7 @@ public class DeviceTaskScheduler {
.
requestRecovery
(
true
)
.
build
();
Date
executeTime
=
Date
.
from
(
Instant
.
now
().
plus
(
7
,
ChronoUnit
.
MINUTES
));
Date
executeTime
=
Date
.
from
(
Instant
.
now
().
plus
(
15
,
ChronoUnit
.
MINUTES
));
SimpleTrigger
trigger
=
TriggerBuilder
.
newTrigger
()
.
withIdentity
(
triggerKey
)
.
forJob
(
jobKey
)
...
...
zhmes-agecal-system/src/main/java/com/zehong/system/task/PrepareFinalExecutionJob.java
0 → 100644
View file @
debf3249
package
com
.
zehong
.
system
.
task
;
import
com.serotonin.modbus4j.ModbusFactory
;
import
com.serotonin.modbus4j.ModbusMaster
;
import
com.serotonin.modbus4j.exception.ModbusInitException
;
import
com.serotonin.modbus4j.exception.ModbusTransportException
;
import
com.serotonin.modbus4j.ip.IpParameters
;
import
com.serotonin.modbus4j.ip.tcp.TcpMaster
;
import
com.serotonin.modbus4j.msg.ModbusResponse
;
import
com.serotonin.modbus4j.msg.ReadHoldingRegistersRequest
;
import
com.serotonin.modbus4j.msg.ReadHoldingRegistersResponse
;
import
com.zehong.system.domain.PalletDeviceBinding
;
import
com.zehong.system.domain.SysRealTimeAdRange
;
import
com.zehong.system.domain.TEquipmentAlarmData
;
import
com.zehong.system.domain.TStoreyInfo
;
import
com.zehong.system.mapper.PalletDeviceBindingMapper
;
import
com.zehong.system.mapper.SysRealTimeAdRangeMapper
;
import
com.zehong.system.mapper.TStoreyInfoMapper
;
import
com.zehong.system.modbus.handler.ModbusResultHandler
;
import
com.zehong.system.modbus.util.Modbus4jUtils
;
import
com.zehong.system.service.ITEquipmentAlarmDataService
;
import
org.apache.commons.lang3.StringUtils
;
import
org.quartz.*
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
import
java.util.Arrays
;
import
java.util.Calendar
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.concurrent.*
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.stream.Collectors
;
/**
* @author lenovo
* @date 2025/11/21
* @description 71 小时后执行的任务
*/
@Component
@DisallowConcurrentExecution
// 禁止同一任务并行执行(必须保留)
public
class
PrepareFinalExecutionJob
implements
Job
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
DeviceCommunicationJob
.
class
);
// -------------------------- 常量配置(统一管理,避免魔法值)--------------------------
// 超时控制:必须小于Cron周期(假设Cron为5分钟,这里留1分钟缓冲)
private
static
final
int
TOTAL_TASK_TIMEOUT_SEC
=
240
;
// 任务总超时:4分钟
private
static
final
int
SINGLE_DEVICE_TIMEOUT_SEC
=
10
;
// 单个设备超时:10秒
// Modbus配置:取消内置重试,统一用自定义重试
private
static
final
int
MODBUS_CONN_TIMEOUT_MS
=
3000
;
// 连接超时:3秒
private
static
final
int
CUSTOM_RETRY_TIMES
=
2
;
// 自定义重试次数:1次
// Modbus寄存器配置
private
static
final
int
REG_START_ADDR
=
0
;
private
static
final
int
REG_READ_COUNT
=
10
;
// 全局线程池 - 避免重复创建
private
static
final
ExecutorService
GLOBAL_DEVICE_EXECUTOR
=
new
ThreadPoolExecutor
(
50
,
100
,
60
,
TimeUnit
.
SECONDS
,
new
LinkedBlockingQueue
<>(
500
),
r
->
new
Thread
(
r
,
"prepare-global-modbus-device"
),
new
ThreadPoolExecutor
.
CallerRunsPolicy
()
);
// 工厂(单例)
private
static
final
ModbusFactory
modbusFactory
=
new
ModbusFactory
();
// -------------------------- 依赖注入 --------------------------
@Resource
private
ITEquipmentAlarmDataService
alarmDataService
;
@Resource
private
TStoreyInfoMapper
tStoreyInfoMapper
;
@Resource
private
PalletDeviceBindingMapper
palletDeviceBindingMapper
;
@Resource
private
SysRealTimeAdRangeMapper
sysRealTimeAdRangeMapper
;
// -------------------------- 核心执行逻辑 --------------------------
@Override
public
void
execute
(
JobExecutionContext
context
)
{
String
storeyIdStr
=
getStoreyIdFromContext
(
context
);
long
startTime
=
System
.
currentTimeMillis
();
try
{
TStoreyInfo
storeyInfo
=
validateAndGetStoreyInfo
(
storeyIdStr
);
// 并行处理3个端口
List
<
CompletableFuture
<
Void
>>
portFutures
=
Arrays
.
asList
(
processPort
(
storeyInfo
,
501
,
Arrays
.
asList
(
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
)),
processPort
(
storeyInfo
,
502
,
Arrays
.
asList
(
28
,
29
,
30
,
31
,
32
,
33
,
34
,
35
,
36
,
37
,
38
,
39
,
40
,
41
,
42
,
43
,
44
,
45
,
46
,
47
,
48
,
49
,
50
,
51
,
52
,
53
,
54
)),
processPort
(
storeyInfo
,
503
,
Arrays
.
asList
(
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
,
66
,
67
,
68
,
69
,
70
,
71
,
72
))
);
// 等待所有端口完成,带总超时
CompletableFuture
<
Void
>
allPorts
=
CompletableFuture
.
allOf
(
portFutures
.
toArray
(
new
CompletableFuture
[
0
])
);
allPorts
.
get
(
TOTAL_TASK_TIMEOUT_SEC
,
TimeUnit
.
SECONDS
);
log
.
info
(
"任务执行成功: fStoreyId={}, 耗时={}ms"
,
storeyIdStr
,
System
.
currentTimeMillis
()
-
startTime
);
}
catch
(
TimeoutException
e
)
{
log
.
warn
(
"任务执行超时: fStoreyId={}"
,
storeyIdStr
);
recordAlarm
(
null
,
storeyIdStr
,
"任务执行超时"
);
}
catch
(
Exception
e
)
{
log
.
error
(
"任务执行异常: fStoreyId={}"
,
storeyIdStr
,
e
);
recordAlarm
(
null
,
storeyIdStr
,
"任务执行异常: "
+
e
.
getMessage
());
}
}
/**
* 处理单个端口的所有设备
*/
private
CompletableFuture
<
Void
>
processPort
(
TStoreyInfo
storeyInfo
,
int
port
,
List
<
Integer
>
deviceIds
)
{
return
CompletableFuture
.
runAsync
(()
->
{
String
ip
=
storeyInfo
.
getfIp
();
String
storeyIdStr
=
storeyInfo
.
getfStoreyId
().
toString
();
log
.
info
(
"开始端口通信: ip={}, port={}, 设备数={}"
,
ip
,
port
,
deviceIds
.
size
());
AtomicInteger
errorCount
=
new
AtomicInteger
(
0
);
// 并行处理该端口的所有设备
List
<
CompletableFuture
<
Boolean
>>
deviceFutures
=
deviceIds
.
stream
()
.
map
(
deviceId
->
processDeviceWithWrite
(
ip
,
port
,
deviceId
,
errorCount
))
.
collect
(
Collectors
.
toList
());
try
{
// 等待该端口所有设备完成
CompletableFuture
<
Void
>
allDevices
=
CompletableFuture
.
allOf
(
deviceFutures
.
toArray
(
new
CompletableFuture
[
0
])
);
// 端口超时 = 设备数 * 单设备超时 / 并发因子
int
portTimeout
=
Math
.
max
(
30
,
deviceIds
.
size
()
*
SINGLE_DEVICE_TIMEOUT_SEC
/
5
);
allDevices
.
get
(
portTimeout
,
TimeUnit
.
SECONDS
);
}
catch
(
TimeoutException
e
)
{
log
.
warn
(
"端口{}通信超时: ip={}, fStoreyId={}"
,
port
,
ip
,
storeyIdStr
);
recordAlarm
(
storeyInfo
,
"端口"
+
port
+
"通信超时"
);
}
catch
(
Exception
e
)
{
log
.
error
(
"端口{}通信异常: ip={}, fStoreyId={}"
,
port
,
ip
,
storeyIdStr
,
e
);
}
if
(
errorCount
.
get
()
>
0
)
{
log
.
warn
(
"端口{}部分设备失败: 失败数={}, fStoreyId={}"
,
port
,
errorCount
.
get
(),
storeyIdStr
);
}
log
.
info
(
"端口通信完成: ip={}, port={}, fStoreyId={}"
,
ip
,
port
,
storeyIdStr
);
},
GLOBAL_DEVICE_EXECUTOR
);
}
/**
* 处理单个设备(读取 + 条件写入)
*/
private
CompletableFuture
<
Boolean
>
processDeviceWithWrite
(
String
ip
,
int
port
,
int
deviceId
,
AtomicInteger
errorCount
)
{
return
CompletableFuture
.
supplyAsync
(()
->
{
ModbusMaster
master
=
null
;
PalletDeviceBinding
binding
=
null
;
try
{
// 1. 读取设备数据
int
[]
result
=
readDeviceWithRetry
(
ip
,
port
,
deviceId
);
// 2. 查询设备绑定信息
binding
=
palletDeviceBindingMapper
.
selectByTrayIdAndIndex
(
ip
,
deviceId
);
if
(
binding
==
null
)
{
log
.
warn
(
"未找到设备绑定: ip={}, deviceId={}"
,
ip
,
deviceId
);
recordAlarm
(
null
,
"ip:"
+
ip
+
",port:"
+
port
+
",deviceId:"
+
deviceId
,
"未找到设备绑定"
);
errorCount
.
incrementAndGet
();
return
false
;
}
// 3. 更新设备状态
binding
.
setStatus
(
String
.
valueOf
(
result
[
1
]));
// 3. 更新浓度值
binding
.
setConcentration
(
String
.
valueOf
(
result
[
0
]));
// 4. 更新AD值
int
realAd
=
result
[
2
];
binding
.
setRealTimeAd
(
realAd
);
SysRealTimeAdRange
topOne
=
sysRealTimeAdRangeMapper
.
getTopOne
();
if
(
topOne
!=
null
&&
realAd
>=
topOne
.
getRealTimeAdMin
()
&&
realAd
<=
topOne
.
getRealTimeAdMax
())
{
binding
.
setRealTimeStatus
(
"1"
);
}
else
{
binding
.
setRealTimeStatus
(
"0"
);
}
// 4. 条件写入时间
if
(
result
[
1
]
==
1
||
result
[
1
]
==
3
||
result
[
1
]
==
4
)
{
// 重用之前的master连接进行写操作
master
=
createModbusMaster
(
ip
,
port
);
checkAndUpdateTime
(
master
,
deviceId
,
binding
);
}
else
{
binding
.
setStatus
(
result
[
1
]
+
""
);
}
// 5. 更新数据库
palletDeviceBindingMapper
.
updatePalletDeviceBinding
(
binding
);
log
.
debug
(
"设备{}处理完成: ip={}, port={}, status={}"
,
deviceId
,
ip
,
port
,
result
[
1
]);
return
true
;
}
catch
(
Exception
e
)
{
log
.
error
(
"设备{}处理异常: ip={}, port={}"
,
deviceId
,
ip
,
port
,
e
);
if
(
binding
==
null
)
{
binding
=
palletDeviceBindingMapper
.
selectByTrayIdAndIndex
(
ip
,
deviceId
);
}
binding
.
setStatus
(
"5"
);
binding
.
setWriteTimeStatus
(
"0"
);
binding
.
setRealTimeStatus
(
"0"
);
palletDeviceBindingMapper
.
updatePalletDeviceBinding
(
binding
);
errorCount
.
incrementAndGet
();
return
false
;
}
finally
{
destroyModbusMaster
(
master
,
deviceId
);
}
},
GLOBAL_DEVICE_EXECUTOR
);
}
/**
* 验证参数并获取设备信息(参数错误直接抛出异常)
*/
private
TStoreyInfo
validateAndGetStoreyInfo
(
String
storeyIdStr
)
{
if
(
StringUtils
.
isBlank
(
storeyIdStr
))
{
log
.
error
(
"fStoreyId参数为空"
);
return
null
;
}
try
{
Long
storeyId
=
Long
.
parseLong
(
storeyIdStr
);
TStoreyInfo
storeyInfo
=
tStoreyInfoMapper
.
selectTStoreyInfoById
(
storeyId
);
if
(
storeyInfo
==
null
||
StringUtils
.
isBlank
(
storeyInfo
.
getfIp
()))
{
log
.
error
(
"设备信息无效: fStoreyId={}"
,
storeyIdStr
);
return
null
;
}
return
storeyInfo
;
}
catch
(
NumberFormatException
e
)
{
log
.
error
(
"fStoreyId格式错误: {}"
,
storeyIdStr
);
return
null
;
}
}
/**
* 带重试的设备读取
*/
private
int
[]
readDeviceWithRetry
(
String
ip
,
int
port
,
int
deviceId
)
{
ModbusMaster
master
=
null
;
int
[]
lastResult
=
null
;
// 用于记录最后一次读取的结果(无论是否满足停止条件)
try
{
// 只创建一次ModbusMaster,循环内复用
master
=
createModbusMaster
(
ip
,
port
);
for
(
int
retry
=
0
;
retry
<=
CUSTOM_RETRY_TIMES
;
retry
++)
{
try
{
// 执行读取操作,获取本次结果
int
[]
currentResult
=
readDeviceRegisters
(
master
,
deviceId
);
// 更新最后一次结果(无论是否满足停止条件,都记录)
lastResult
=
currentResult
;
// 检查停止条件,如果满足则提前返回(无需等到重试耗尽)
if
(
ModbusResultHandler
.
createDefaultStopCondition
().
test
(
currentResult
))
{
log
.
info
(
"设备{}第{}次读取成功(满足条件): ip={}, port={}"
,
deviceId
,
retry
+
1
,
ip
,
port
);
return
currentResult
;
}
// 未满足条件且不是最后一次重试,休眠后继续
if
(
retry
<
CUSTOM_RETRY_TIMES
)
{
log
.
info
(
"设备{}第{}次读取未满足条件,准备重试: ip={}, port={}"
,
deviceId
,
retry
+
1
,
ip
,
port
);
Thread
.
sleep
(
200
);
}
}
catch
(
Exception
e
)
{
// 本次读取发生异常,记录日志但不中断重试(继续下一次)
log
.
warn
(
"设备{}第{}次读取发生异常: ip={}, port={}"
,
deviceId
,
retry
+
1
,
ip
,
port
,
e
);
// 如果是最后一次重试,异常时lastResult可能为null(需后续处理)
}
}
// 循环结束(重试耗尽),此时lastResult为最后一次的结果(可能是正常读取但不满足条件,或null)
log
.
info
(
"设备{}重试次数耗尽,返回最后一次结果: ip={}, port={}"
,
deviceId
,
ip
,
port
);
}
catch
(
Exception
e
)
{
// 捕获创建ModbusMaster或休眠时的异常(非读取操作的异常)
log
.
error
(
"设备{}连接创建或休眠失败: ip={}, port={}"
,
deviceId
,
ip
,
port
,
e
);
throw
new
RuntimeException
(
"设备连接或操作异常"
,
e
);
}
finally
{
// 无论结果如何,最终销毁连接
destroyModbusMaster
(
master
,
deviceId
);
}
// 处理最后一次结果可能为null的情况(例如所有重试都异常)
if
(
lastResult
==
null
)
{
throw
new
RuntimeException
(
"设备所有读取尝试均失败(无有效结果)"
);
}
return
lastResult
;
}
/**
* 检查并更新时间
*/
private
void
checkAndUpdateTime
(
ModbusMaster
master
,
int
deviceId
,
PalletDeviceBinding
binding
)
{
try
{
int
[]
timeRegisters
=
Modbus4jUtils
.
readDeviceRegisters
(
master
,
deviceId
);
if
(
timeRegisters
.
length
<
9
)
{
log
.
warn
(
"设备{}时间寄存器读取失败或数据长度不足"
,
deviceId
);
binding
.
setWriteTimeStatus
(
"0"
);
binding
.
setRealTimeStatus
(
"0"
);
recordAlarmByBinding
(
binding
,
"设备时间寄存器读取失败"
);
return
;
}
int
deviceYear
=
timeRegisters
[
4
];
int
deviceMonth
=
timeRegisters
[
5
];
int
deviceDay
=
timeRegisters
[
6
];
int
deviceHour
=
timeRegisters
[
7
];
int
deviceMinute
=
timeRegisters
[
8
];
log
.
info
(
"设备{}当前时间: {}-{}-{} {}:{}"
,
deviceId
,
deviceYear
,
deviceMonth
,
deviceDay
,
deviceHour
,
deviceMinute
);
// 2. 获取系统当前时间
Calendar
systemCal
=
Calendar
.
getInstance
();
int
systemYear
=
systemCal
.
get
(
Calendar
.
YEAR
);
int
systemMonth
=
systemCal
.
get
(
Calendar
.
MONTH
)
+
1
;
// Calendar月份从0开始
int
systemDay
=
systemCal
.
get
(
Calendar
.
DATE
);
int
systemHour
=
systemCal
.
get
(
Calendar
.
HOUR_OF_DAY
);
int
systemMinute
=
systemCal
.
get
(
Calendar
.
MINUTE
);
log
.
info
(
"系统当前时间: {}-{}-{} {}:{}"
,
systemYear
,
systemMonth
,
systemDay
,
systemHour
,
systemMinute
);
// 3. 比较时间差异
if
(
isTimeConsistent
(
deviceYear
,
deviceMonth
,
deviceDay
,
deviceHour
,
deviceMinute
,
systemYear
,
systemMonth
,
systemDay
,
systemHour
,
systemMinute
))
{
// 时间一致
handleTimeConsistent
(
deviceId
,
binding
);
}
else
{
// 时间不一致
handleTimeInconsistent
(
master
,
deviceId
,
binding
,
systemCal
);
}
}
catch
(
ModbusTransportException
e
)
{
binding
.
setWriteTimeStatus
(
"0"
);
binding
.
setRealTimeStatus
(
"0"
);
log
.
error
(
"设备{}时间写入异常"
,
deviceId
,
e
);
recordAlarmByBinding
(
binding
,
"设备时间写入异常: "
+
e
.
getMessage
());
}
}
/**
* 判断设备时间与系统时间是否一致(差异在2分钟内)
* 考虑跨年、跨月等边界情况
*/
private
boolean
isTimeConsistent
(
int
deviceYear
,
int
deviceMonth
,
int
deviceDay
,
int
deviceHour
,
int
deviceMinute
,
int
systemYear
,
int
systemMonth
,
int
systemDay
,
int
systemHour
,
int
systemMinute
)
{
// 1. 首先检查年份差异(考虑跨年)
if
(
Math
.
abs
(
deviceYear
-
systemYear
)
>
1
)
{
log
.
debug
(
"年份差异超过1年: 设备{}年 vs 系统{}年"
,
deviceYear
,
systemYear
);
return
false
;
}
// 2. 转换为总分钟数进行比较(考虑跨年、跨月、跨日)
long
deviceTotalMinutes
=
calculateTotalMinutes
(
deviceYear
,
deviceMonth
,
deviceDay
,
deviceHour
,
deviceMinute
);
long
systemTotalMinutes
=
calculateTotalMinutes
(
systemYear
,
systemMonth
,
systemDay
,
systemHour
,
systemMinute
);
long
minuteDiff
=
Math
.
abs
(
deviceTotalMinutes
-
systemTotalMinutes
);
log
.
debug
(
"时间差异比较: 设备分钟数={}, 系统分钟数={}, 差异={}分钟"
,
deviceTotalMinutes
,
systemTotalMinutes
,
minuteDiff
);
// 3. 差异在2分钟内认为一致
return
minuteDiff
<=
2
;
}
/**
* 处理时间一致的情况
*/
private
void
handleTimeConsistent
(
int
deviceId
,
PalletDeviceBinding
binding
)
{
log
.
info
(
"设备{}时间与系统时间一致,无需更新"
,
deviceId
);
binding
.
setWriteTimeStatus
(
"1"
);
// 时间状态正常
log
.
info
(
"设备{}时间检查完成:时间一致"
,
deviceId
);
}
/**
* 处理时间不一致的情况 - 更新设备时间
*/
private
void
handleTimeInconsistent
(
ModbusMaster
master
,
int
deviceId
,
PalletDeviceBinding
binding
,
Calendar
systemCal
)
{
log
.
info
(
"设备{}时间与系统时间不一致,开始更新时间"
,
deviceId
);
try
{
// 1 如果时间状态为空,则写入时间
if
(
binding
.
getWriteTimeStatus
()
==
null
)
{
int
year
=
systemCal
.
get
(
Calendar
.
YEAR
);
int
month
=
systemCal
.
get
(
Calendar
.
MONTH
)
+
1
;
int
day
=
systemCal
.
get
(
Calendar
.
DATE
);
int
hour
=
systemCal
.
get
(
Calendar
.
HOUR_OF_DAY
);
int
minute
=
systemCal
.
get
(
Calendar
.
MINUTE
);
// 写入时间寄存器
boolean
success
;
success
=
Modbus4jUtils
.
writeRegister
(
master
,
deviceId
,
4
,
(
short
)
year
);
success
=
success
&&
Modbus4jUtils
.
writeRegister
(
master
,
deviceId
,
5
,
(
short
)
month
);
success
=
success
&&
Modbus4jUtils
.
writeRegister
(
master
,
deviceId
,
6
,
(
short
)
day
);
success
=
success
&&
Modbus4jUtils
.
writeRegister
(
master
,
deviceId
,
7
,
(
short
)
hour
);
success
=
success
&&
Modbus4jUtils
.
writeRegister
(
master
,
deviceId
,
8
,
(
short
)
minute
);
if
(
success
)
{
binding
.
setRecordYear
(
String
.
valueOf
(
year
));
binding
.
setRecordMonth
(
String
.
valueOf
(
month
));
binding
.
setRecordDate
(
String
.
valueOf
(
day
));
binding
.
setRecordHour
(
String
.
valueOf
(
hour
));
binding
.
setRecordMinute
(
String
.
valueOf
(
minute
));
binding
.
setWriteTimeStatus
(
"1"
);
log
.
info
(
"设备{}时间更新成功: {}-{}-{} {}:{}"
,
deviceId
,
year
,
month
,
day
,
hour
,
minute
);
}
else
{
binding
.
setWriteTimeStatus
(
"0"
);
log
.
error
(
"设备{}时间更新失败"
,
deviceId
);
recordAlarmByBinding
(
binding
,
"设备时间更新失败"
);
}
// 2. 如果时间状态为1,则更新 时间运行状态 为异常 状态
}
else
if
(
"1"
.
equals
(
binding
.
getWriteTimeStatus
()))
{
log
.
info
(
"设备{}时间状态为1,则更新 时间运行状态 为异常 状态"
,
deviceId
);
binding
.
setRunTimeStatus
(
"0"
);
}
// 3. 写时间状态 异常状态;不管
}
catch
(
Exception
e
)
{
binding
.
setWriteTimeStatus
(
"0"
);
log
.
error
(
"设备{}时间更新异常"
,
deviceId
,
e
);
recordAlarmByBinding
(
binding
,
"设备时间更新异常: "
+
e
.
getMessage
());
}
}
/**
* 计算从参考时间点(如2000年)开始的总分钟数
* 用于准确比较时间差异,考虑跨年跨月
*/
private
long
calculateTotalMinutes
(
int
year
,
int
month
,
int
day
,
int
hour
,
int
minute
)
{
// 使用2000-01-01 00:00:00作为参考点
Calendar
cal
=
Calendar
.
getInstance
();
cal
.
set
(
Calendar
.
YEAR
,
2000
);
cal
.
set
(
Calendar
.
MONTH
,
Calendar
.
JANUARY
);
cal
.
set
(
Calendar
.
DAY_OF_MONTH
,
1
);
cal
.
set
(
Calendar
.
HOUR_OF_DAY
,
0
);
cal
.
set
(
Calendar
.
MINUTE
,
0
);
cal
.
set
(
Calendar
.
SECOND
,
0
);
cal
.
set
(
Calendar
.
MILLISECOND
,
0
);
long
baseTimeInMillis
=
cal
.
getTimeInMillis
();
// 设置目标时间
cal
.
set
(
Calendar
.
YEAR
,
year
);
cal
.
set
(
Calendar
.
MONTH
,
month
-
1
);
// 转换为Calendar月份(0-based)
cal
.
set
(
Calendar
.
DAY_OF_MONTH
,
day
);
cal
.
set
(
Calendar
.
HOUR_OF_DAY
,
hour
);
cal
.
set
(
Calendar
.
MINUTE
,
minute
);
cal
.
set
(
Calendar
.
SECOND
,
0
);
cal
.
set
(
Calendar
.
MILLISECOND
,
0
);
long
targetTimeInMillis
=
cal
.
getTimeInMillis
();
// 返回总分钟数
return
(
targetTimeInMillis
-
baseTimeInMillis
)
/
(
1000
*
60
);
}
/**
* 写入当前时间到设备
*/
private
void
writeCurrentTimeToDevice
(
ModbusMaster
master
,
int
deviceId
,
PalletDeviceBinding
binding
)
{
try
{
Calendar
cal
=
Calendar
.
getInstance
();
int
year
=
cal
.
get
(
Calendar
.
YEAR
);
int
month
=
cal
.
get
(
Calendar
.
MONTH
)
+
1
;
int
day
=
cal
.
get
(
Calendar
.
DATE
);
int
hour
=
cal
.
get
(
Calendar
.
HOUR_OF_DAY
);
int
minute
=
cal
.
get
(
Calendar
.
MINUTE
);
// 写入时间寄存器
boolean
success
;
success
=
Modbus4jUtils
.
writeRegister
(
master
,
deviceId
,
4
,
(
short
)
year
);
success
&=
Modbus4jUtils
.
writeRegister
(
master
,
deviceId
,
5
,
(
short
)
month
);
success
&=
Modbus4jUtils
.
writeRegister
(
master
,
deviceId
,
6
,
(
short
)
day
);
success
&=
Modbus4jUtils
.
writeRegister
(
master
,
deviceId
,
7
,
(
short
)
hour
);
success
&=
Modbus4jUtils
.
writeRegister
(
master
,
deviceId
,
8
,
(
short
)
minute
);
if
(
success
)
{
binding
.
setRecordYear
(
String
.
valueOf
(
year
));
binding
.
setRecordMonth
(
String
.
valueOf
(
month
));
binding
.
setRecordDate
(
String
.
valueOf
(
day
));
binding
.
setRecordHour
(
String
.
valueOf
(
hour
));
binding
.
setRecordMinute
(
String
.
valueOf
(
minute
));
log
.
debug
(
"设备{}时间写入成功"
,
deviceId
);
}
else
{
binding
.
setWriteTimeStatus
(
"0"
);
recordAlarmByBinding
(
binding
,
"设备时间写入失败"
);
}
}
catch
(
Exception
e
)
{
binding
.
setWriteTimeStatus
(
"0"
);
log
.
error
(
"设备{}时间写入异常"
,
deviceId
,
e
);
recordAlarmByBinding
(
binding
,
"设备时间写入异常: "
+
e
.
getMessage
());
}
}
// -------------------------- Modbus工具方法(显式抛出异常)--------------------------
/**
* 创建Modbus连接(取消内置重试,统一自定义重试)
*/
private
ModbusMaster
createModbusMaster
(
String
ip
,
int
port
)
throws
ModbusInitException
{
IpParameters
params
=
new
IpParameters
();
params
.
setHost
(
ip
);
params
.
setPort
(
port
);
TcpMaster
master
=
(
TcpMaster
)
modbusFactory
.
createTcpMaster
(
params
,
true
);
master
.
setTimeout
(
MODBUS_CONN_TIMEOUT_MS
);
master
.
setRetries
(
0
);
master
.
init
();
return
master
;
}
/**
* 读取设备寄存器(异常直接抛出)
*/
private
int
[]
readDeviceRegisters
(
ModbusMaster
master
,
int
deviceId
)
throws
ModbusTransportException
{
ReadHoldingRegistersRequest
request
=
Modbus4jUtils
.
getReadHoldingRegistersRequest
(
deviceId
,
REG_START_ADDR
,
REG_READ_COUNT
);
ModbusResponse
response
=
master
.
send
(
request
);
if
(!(
response
instanceof
ReadHoldingRegistersResponse
))
{
log
.
info
(
"无效Modbus响应类型:"
+
response
.
getClass
().
getName
()
+
",deviceId="
+
deviceId
);
}
assert
response
instanceof
ReadHoldingRegistersResponse
;
ReadHoldingRegistersResponse
regResp
=
(
ReadHoldingRegistersResponse
)
response
;
short
[]
signedVals
=
regResp
.
getShortData
();
int
[]
unsignedVals
=
new
int
[
signedVals
.
length
];
for
(
int
i
=
0
;
i
<
signedVals
.
length
;
i
++)
{
unsignedVals
[
i
]
=
signedVals
[
i
]
&
0xFFFF
;
// 转换为无符号整数
}
log
.
info
(
"设备寄存器读取结果:deviceId={},值={}"
,
deviceId
,
Arrays
.
toString
(
unsignedVals
));
return
unsignedVals
;
}
/**
* 销毁Modbus连接(反射失败直接抛出异常,显式暴露问题)
*/
private
void
destroyModbusMaster
(
ModbusMaster
master
,
int
deviceId
)
{
if
(
master
!=
null
)
{
try
{
master
.
destroy
();
}
catch
(
Exception
e
)
{
log
.
debug
(
"设备{}: ModbusMaster销毁异常"
,
deviceId
,
e
);
}
}
}
// -------------------------- 辅助方法(日志/告警)--------------------------
/**
* 从JobContext中获取fStoreyId(失败返回unknown)
*/
private
String
getStoreyIdFromContext
(
JobExecutionContext
context
)
{
try
{
JobDataMap
data
=
context
.
getJobDetail
().
getJobDataMap
();
return
data
!=
null
?
data
.
getString
(
"fStoreyId"
)
:
"unknown"
;
}
catch
(
Exception
e
)
{
log
.
error
(
"从JobContext获取fStoreyId失败"
,
e
);
return
"unknown"
;
}
}
/**
* 记录告警(兼容设备信息为空的场景)
*/
private
void
recordAlarm
(
TStoreyInfo
storeyInfo
,
String
equipmentCode
,
String
alarmData
)
{
try
{
TEquipmentAlarmData
alarm
=
new
TEquipmentAlarmData
();
alarm
.
setfAlarmType
(
"03"
);
// 老化层告警
alarm
.
setfEquipmentCode
(
storeyInfo
!=
null
?
storeyInfo
.
getfStoreyCode
()
:
equipmentCode
);
alarm
.
setfAlarmData
(
alarmData
);
alarm
.
setfCreateTime
(
new
Date
());
alarmDataService
.
insertTEquipmentAlarmData
(
alarm
);
log
.
debug
(
"告警记录成功:设备编码={},内容={}"
,
alarm
.
getfEquipmentCode
(),
alarmData
);
}
catch
(
Exception
e
)
{
log
.
error
(
"告警记录失败:设备编码={},内容={}"
,
equipmentCode
,
alarmData
,
e
);
}
}
/**
* 简化告警记录(设备信息非空时)
*/
private
void
recordAlarm
(
TStoreyInfo
storeyInfo
,
String
alarmData
)
{
recordAlarm
(
storeyInfo
,
storeyInfo
!=
null
?
storeyInfo
.
getfStoreyCode
()
:
"unknown"
,
alarmData
);
}
/**
* 统一告警记录(修复字段错误,确保写入成功)
*/
private
void
recordAlarmByBinding
(
PalletDeviceBinding
binding
,
String
alarmMsg
)
{
String
equipmentCode
=
binding
!=
null
?
binding
.
getDeviceCode
()
:
"unknown"
;
recordAlarmByBingding
(
equipmentCode
,
alarmMsg
);
}
private
void
recordAlarmByBingding
(
String
equipmentCode
,
String
alarmMsg
)
{
try
{
TEquipmentAlarmData
alarm
=
new
TEquipmentAlarmData
();
alarm
.
setfAlarmType
(
"04"
);
// 04.点位告警
alarm
.
setfEquipmentCode
(
equipmentCode
);
alarm
.
setfAlarmData
(
alarmMsg
);
alarm
.
setfCreateTime
(
new
Date
());
// 修复字段错误:用fCreateTime而非createTime
alarmDataService
.
insertTEquipmentAlarmData
(
alarm
);
log
.
debug
(
"告警记录成功:equipmentCode={}, msg={}"
,
equipmentCode
,
alarmMsg
);
}
catch
(
Exception
e
)
{
log
.
error
(
"告警记录失败:equipmentCode={}, msg={}"
,
equipmentCode
,
alarmMsg
,
e
);
}
}
}
zhmes-agecal-system/src/main/resources/mapper/system/PalletDeviceBindingMapper.xml
View file @
debf3249
...
...
@@ -24,8 +24,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result
property=
"writeTimeStatus"
column=
"f_write_time_status"
/>
<result
property=
"adjustmentZeroAd"
column=
"f_adjustment_zero_ad"
/>
<result
property=
"zeroStatus"
column=
"f_zero_status"
/>
<result
property=
"calibrationAd"
column=
"f_calibration_ad"
/>
<result
property=
"calibrationAdStatus"
column=
"f_calibration_status"
/>
<result
property=
"concentration"
column=
"f_concentration"
/>
<result
property=
"runTimeStatus"
column=
"f_run_time_status"
/>
<result
property=
"realTimeAd"
column=
"f_real_time_ad"
/>
<result
property=
"realTimeStatus"
column=
"f_real_time_ad_status"
/>
</resultMap>
<sql
id=
"selectPalletDeviceBindingVo"
>
...
...
@@ -48,8 +55,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
palDeviceBinding.f_record_minute,
palDeviceBinding.f_write_time_status,
palDeviceBinding.f_adjustment_zero_ad,
palDeviceBinding.f_zero_status,
palDeviceBinding.f_calibration_ad,
palDeviceBinding.f_concentration
palDeviceBinding.f_calibration_status,
palDeviceBinding.f_concentration,
palDeviceBinding.f_run_time_status,
palDeviceBinding.f_real_time_ad,
palDeviceBinding.f_real_time_ad_status
from t_pallet_device_binding palDeviceBinding
left join t_tray_info trayInfo on trayInfo.f_tray_id = palDeviceBinding.f_tray_id
</sql>
...
...
@@ -83,13 +95,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if
test=
"createTime != null "
>
and palDeviceBinding.f_create_time = #{createTime}
</if>
<if
test=
"status != null and status != '' "
>
and palDeviceBinding.f_status = #{status}
</if>
</where>
order by palDeviceBinding.f_index asc
order by
trayInfo.f_tray_code ,
palDeviceBinding.f_index asc
</select>
<select
id=
"getAllExcludeUnbindingTimeByTrayId"
parameterType=
"long"
resultMap=
"PalletDeviceBindingResult"
>
<include
refid=
"selectPalletDeviceBindingVo"
/>
where palDeviceBinding.f_tray_id = #{trayId}
order by palDeviceBinding.f_index asc
</select>
<select
id=
"listByTrayCode"
parameterType=
"string"
resultMap=
"PalletDeviceBindingResult"
>
<include
refid=
"selectPalletDeviceBindingVo"
/>
where trayInfo.f_tray_code = #{trayCode}
</select>
<select
id=
"selectPalletDeviceBindingById"
parameterType=
"Long"
resultMap=
"PalletDeviceBindingResult"
>
<include
refid=
"selectPalletDeviceBindingVo"
/>
...
...
@@ -114,8 +130,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
f_record_minute ,
f_write_time_status,
f_adjustment_zero_ad,
f_zero_status,
f_calibration_ad,
f_concentration
f_calibration_status,
f_concentration,
f_run_time_status,
f_real_time_ad,
f_real_time_ad_status
from t_pallet_device_binding palDeviceBinding where palDeviceBinding.f_tray_id = (
SELECT
trayInfo.f_tray_id
...
...
@@ -151,8 +172,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
f_record_minute = null,
f_write_time_status = null,
f_adjustment_zero_ad = null,
f_zero_status = null,
f_calibration_ad = null,
f_concentration = null
f_calibration_status = null,
f_concentration = null,
f_calibration_status = null,
f_run_time_status = null,
f_real_time_ad = null,
f_real_time_ad_status = null
where f_tray_id = #{trayId}
</update>
<insert
id=
"insertPalletDeviceBinding"
parameterType=
"PalletDeviceBinding"
useGeneratedKeys=
"true"
keyProperty=
"palletDeviceBindingId"
>
...
...
@@ -194,8 +221,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
f_record_minute = null,
f_write_time_status = null,
f_adjustment_zero_ad = null,
f_zero_status = null,
f_calibration_ad = null,
f_concentration = null
f_calibration_status = null,
f_concentration = null,
f_run_time_status = null,
f_real_time_ad = null,
f_real_time_ad_status = null
where f_pallet_device_binding_id = #{palletDeviceBindingId}
</update>
<update
id=
"updatePalletDeviceBinding"
parameterType=
"PalletDeviceBinding"
>
...
...
@@ -220,8 +252,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if
test=
"recordMinute != null"
>
f_record_minute = #{recordMinute},
</if>
<if
test=
"writeTimeStatus != null"
>
f_write_time_status = #{writeTimeStatus},
</if>
<if
test=
"adjustmentZeroAd != null"
>
f_adjustment_zero_ad = #{adjustmentZeroAd},
</if>
<if
test=
"zeroStatus != null"
>
f_zero_status = #{zeroStatus},
</if>
<if
test=
"calibrationAd != null"
>
f_calibration_ad = #{calibrationAd},
</if>
<if
test=
"concentration != null"
>
f_concentration = #{concentration},
</if>
<if
test=
"calibrationAdStatus != null"
>
f_calibration_status = #{calibrationAdStatus},
</if>
<if
test=
"runTimeStatus != null"
>
f_run_time_status = #{runTimeStatus},
</if>
<if
test=
"realTimeAd != null"
>
f_real_time_ad = #{realTimeAd},
</if>
<if
test=
"realTimeStatus != null"
>
f_real_time_status = #{realTimeStatus},
</if>
</trim>
where f_pallet_device_binding_id = #{palletDeviceBindingId}
</update>
...
...
@@ -235,6 +272,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
WHERE f_pallet_device_binding_id = #{item.palletDeviceBindingId}
</foreach>
</update>
<update
id=
"batchUpdateAdAndStatus"
parameterType=
"list"
>
<foreach
collection=
"palletDeviceBindingList"
item=
"item"
index=
"index"
separator=
";"
>
UPDATE t_pallet_device_binding
<trim
prefix=
"SET"
suffixOverrides=
","
>
<if
test=
"item.adjustmentZeroAd != null"
>
f_adjustment_zero_ad = #{item.adjustmentZeroAd},
</if>
<if
test=
"item.zeroStatus == null"
>
f_zero_status = #{item.zeroStatus},
</if>
<if
test=
"item.calibrationAd != null"
>
f_calibration_ad = #{item.calibrationAd},
</if>
<if
test=
"item.calibrationAdStatus != null"
>
f_calibration_status = #{item.calibrationAdStatus},
</if>
</trim>
where f_pallet_device_binding_id = #{item.palletDeviceBindingId}
</foreach>
</update>
<update
id=
"batchUpdateDeviceCodeAndUnbindingTime"
parameterType=
"list"
>
<foreach
collection=
"palletDeviceBindingList"
item=
"item"
index=
"index"
separator=
";"
>
UPDATE t_pallet_device_binding
...
...
@@ -248,8 +297,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
f_record_minute = null,
f_write_time_status = null,
f_adjustment_zero_ad = null,
f_zero_status = null,
f_calibration_ad = null,
f_calibration_status = null,
f_concentration = null,
f_run_time_status = null,
f_real_time_ad = null,
f_real_time_status = null
<if
test=
"item.deviceCode != null"
>
f_device_code = #{item.deviceCode},
</if>
</trim>
WHERE f_pallet_device_binding_id = #{item.palletDeviceBindingId}
...
...
@@ -267,8 +321,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
f_record_minute = null,
f_write_time_status = null,
f_adjustment_zero_ad = null,
f_zero_status = null,
f_calibration_ad = null,
f_concentration = null
f_calibration_status = null,
f_concentration = null,
f_run_time_status = null,
f_real_time_ad = null,
f_real_time_status = null
where f_tray_id = #{trayId}
</update>
...
...
zhmes-agecal-system/src/main/resources/mapper/system/SysConfigMapper.xml
View file @
debf3249
...
...
@@ -97,6 +97,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</set>
where config_id = #{configId}
</update>
<update
id=
"directUpdateConfigByKey"
parameterType=
"SysConfig"
>
update sys_config set config_value = #{configValue} where config_key = #{configKey}
</update>
<delete
id=
"deleteConfigById"
parameterType=
"Long"
>
delete from sys_config where config_id = #{configId}
...
...
zhmes-agecal-system/src/main/resources/mapper/system/SysRealTimeAdRangeMapper.xml
0 → 100644
View file @
debf3249
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.zehong.system.mapper.SysRealTimeAdRangeMapper"
>
<resultMap
type=
"SysRealTimeAdRange"
id=
"SysRealTimeAdRangeResult"
>
<result
property=
"id"
column=
"f_id"
/>
<result
property=
"realTimeAdMin"
column=
"f_real_time_ad_min"
/>
<result
property=
"realTimeAdMax"
column=
"f_real_time_ad_max"
/>
</resultMap>
<sql
id=
"selectSysRealTimeAdRangeVo"
>
select f_id, f_real_time_ad_min, f_real_time_ad_max from t_sys_real_time_ad_range
</sql>
<select
id=
"selectSysRealTimeAdRangeList"
parameterType=
"SysRealTimeAdRange"
resultMap=
"SysRealTimeAdRangeResult"
>
<include
refid=
"selectSysRealTimeAdRangeVo"
/>
<where>
<if
test=
"realTimeAdMin != null "
>
and f_real_time_ad_min = #{realTimeAdMin}
</if>
<if
test=
"realTimeAdMax != null "
>
and f_real_time_ad_max = #{realTimeAdMax}
</if>
</where>
</select>
<select
id=
"getTopOne"
resultMap=
"SysRealTimeAdRangeResult"
>
<include
refid=
"selectSysRealTimeAdRangeVo"
/>
limit 1
</select>
<select
id=
"selectSysRealTimeAdRangeById"
parameterType=
"Long"
resultMap=
"SysRealTimeAdRangeResult"
>
<include
refid=
"selectSysRealTimeAdRangeVo"
/>
where f_id = #{id}
</select>
<insert
id=
"insertSysRealTimeAdRange"
parameterType=
"SysRealTimeAdRange"
useGeneratedKeys=
"true"
keyProperty=
"id"
>
insert into t_sys_real_time_ad_range
<trim
prefix=
"("
suffix=
")"
suffixOverrides=
","
>
<if
test=
"realTimeAdMin != null"
>
f_real_time_ad_min,
</if>
<if
test=
"realTimeAdMax != null"
>
f_real_time_ad_max,
</if>
</trim>
<trim
prefix=
"values ("
suffix=
")"
suffixOverrides=
","
>
<if
test=
"realTimeAdMin != null"
>
#{realTimeAdMin},
</if>
<if
test=
"realTimeAdMax != null"
>
#{realTimeAdMax},
</if>
</trim>
</insert>
<update
id=
"updateSysRealTimeAdRange"
parameterType=
"SysRealTimeAdRange"
>
update t_sys_real_time_ad_range
<trim
prefix=
"SET"
suffixOverrides=
","
>
<if
test=
"realTimeAdMin != null"
>
f_real_time_ad_min = #{realTimeAdMin},
</if>
<if
test=
"realTimeAdMax != null"
>
f_real_time_ad_max = #{realTimeAdMax},
</if>
</trim>
where f_id = #{id}
</update>
<delete
id=
"deleteSysRealTimeAdRangeById"
parameterType=
"Long"
>
delete from t_sys_real_time_ad_range where f_id = #{id}
</delete>
<delete
id=
"deleteSysRealTimeAdRangeByIds"
parameterType=
"String"
>
delete from t_sys_real_time_ad_range where f_id in
<foreach
item=
"id"
collection=
"array"
open=
"("
separator=
","
close=
")"
>
#{id}
</foreach>
</delete>
</mapper>
\ No newline at end of file
zhmes-agecal-system/src/main/resources/mapper/system/TStoreyInfoMapper.xml
View file @
debf3249
...
...
@@ -205,6 +205,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if
test=
"fAgingEndTime != null"
>
f_aging_end_time = #{fAgingEndTime},
</if>
<if
test=
"fAgingEndTime == null"
>
f_aging_end_time = null,
</if>
</trim>
where f_storey_id = #{fStoreyId}
</update>
<update
id=
"unbindByCode"
parameterType=
"TStoreyInfo"
>
...
...
zhmes-agecal-web/src/api/realAdRange/realAdRange.js
0 → 100644
View file @
debf3249
import
request
from
'@/utils/request'
// 查询实时AD范围维护列表
export
function
listRange
(
query
)
{
return
request
({
url
:
'/system/realAdRange/list'
,
method
:
'get'
,
params
:
query
})
}
// 查询实时AD范围维护详细
export
function
getRange
(
id
)
{
return
request
({
url
:
'/system/realAdRange/'
+
id
,
method
:
'get'
})
}
export
function
getTopOne
()
{
return
request
({
url
:
'/system/realAdRange/getTopOne'
,
method
:
'get'
})
}
// 新增实时AD范围维护
export
function
addRange
(
data
)
{
return
request
({
url
:
'/system/realAdRange'
,
method
:
'post'
,
data
:
data
})
}
// 修改实时AD范围维护
export
function
updateRange
(
data
)
{
return
request
({
url
:
'/system/realAdRange'
,
method
:
'put'
,
data
:
data
})
}
// 删除实时AD范围维护
export
function
delRange
(
id
)
{
return
request
({
url
:
'/system/realAdRange/'
+
id
,
method
:
'delete'
})
}
// 导出实时AD范围维护
export
function
exportRange
(
query
)
{
return
request
({
url
:
'/system/realAdRange/export'
,
method
:
'get'
,
params
:
query
})
}
zhmes-agecal-web/src/api/storey/storey.js
View file @
debf3249
...
...
@@ -69,7 +69,7 @@ export function PowerOn(query) {
})
}
export
function
PowerOutage
(
query
)
{
export
function
PowerOutage
(
query
)
{
return
request
({
url
:
'/storey/powerOutage'
,
method
:
'get'
,
...
...
@@ -90,6 +90,14 @@ export function blanking(command) {
})
}
export
function
reAgine
(
query
)
{
return
request
({
url
:
'/storey/handleReAgine/'
,
method
:
'get'
,
params
:
query
})
}
export
function
directBlanking
(
command
)
{
return
request
({
url
:
'/storey/handleDirectBlanking/'
+
command
,
...
...
zhmes-agecal-web/src/api/system/config.js
View file @
debf3249
...
...
@@ -25,6 +25,20 @@ export function getConfigKey(configKey) {
})
}
export
function
getUploadMesAddress
()
{
return
request
({
url
:
'/system/config/getUploadMesAddress'
,
method
:
'get'
})
}
export
function
updateUploadMesAddress
(
data
)
{
return
request
({
url
:
'/system/config/updateUploadMesAddress/'
,
method
:
'post'
,
data
:
data
})
}
// 新增参数配置
export
function
addConfig
(
data
)
{
return
request
({
...
...
zhmes-agecal-web/src/views/realAdRange/index.vue
0 → 100644
View file @
debf3249
<
template
>
<div
class=
"app-container"
>
<el-card
shadow=
"hover"
style=
"max-width: 600px; margin: 0 auto;"
>
<div
slot=
"header"
class=
"clearfix"
>
<span>
实时AD范围维护
</span>
</div>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"rules"
label-width=
"120px"
class=
"mt-4"
>
<el-form-item
label=
"实时AD最小值"
prop=
"realTimeAdMin"
>
<el-input
v-model
.
number=
"form.realTimeAdMin"
type=
"number"
placeholder=
"请输入实时AD最小值 (0-65535)"
:min=
"0"
:max=
"65535"
class=
"w-80"
/>
</el-form-item>
<el-form-item
label=
"实时AD最大值"
prop=
"realTimeAdMax"
>
<el-input
v-model
.
number=
"form.realTimeAdMax"
type=
"number"
placeholder=
"请输入实时AD最大值 (0-65535)"
:min=
"0"
:max=
"65535"
class=
"w-80"
/>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
@
click=
"handleSave"
:loading=
"loading"
>
<i
class=
"el-icon-check"
></i>
保存设置
</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</
template
>
<
script
>
import
{
updateRange
,
getTopOne
,
addRange
}
from
"@/api/realAdRange/realAdRange"
;
export
default
{
name
:
"RealTimeAdRange"
,
data
()
{
return
{
// 加载状态
loading
:
false
,
// 表单数据
form
:
{
realTimeAdMin
:
null
,
realTimeAdMax
:
null
},
// 表单校验规则
rules
:
{
realTimeAdMin
:
[
{
required
:
true
,
message
:
"实时AD最小值不能为空"
,
trigger
:
"blur"
},
{
type
:
"integer"
,
message
:
"实时AD最小值必须为整数"
,
trigger
:
"blur"
},
{
validator
:
(
rule
,
value
,
callback
)
=>
{
if
(
value
<
0
)
{
callback
(
new
Error
(
"实时AD最小值不能小于0"
));
}
else
if
(
value
>
65535
)
{
callback
(
new
Error
(
"实时AD最小值不能大于65535"
));
}
else
{
callback
();
}
},
trigger
:
"blur"
}
],
realTimeAdMax
:
[
{
required
:
true
,
message
:
"实时AD最大值不能为空"
,
trigger
:
"blur"
},
{
type
:
"integer"
,
message
:
"实时AD最大值必须为整数"
,
trigger
:
"blur"
},
{
validator
:
(
rule
,
value
,
callback
)
=>
{
if
(
value
<
0
)
{
callback
(
new
Error
(
"实时AD最大值不能小于0"
));
}
else
if
(
value
>
65535
)
{
callback
(
new
Error
(
"实时AD最大值不能大于65535"
));
}
else
if
(
this
.
form
.
realTimeAdMin
!==
null
&&
value
<=
this
.
form
.
realTimeAdMin
)
{
callback
(
new
Error
(
"实时AD最大值必须大于最小值"
));
}
else
{
callback
();
}
},
trigger
:
"blur"
}
]
}
};
},
created
()
{
// 初始化时加载数据
this
.
fetchData
();
},
methods
:
{
/**
* 加载AD范围数据
*/
fetchData
()
{
this
.
loading
=
true
;
getTopOne
().
then
(
response
=>
{
// 假设接口返回的数据结构是 { realTimeAdMin: xxx, realTimeAdMax: xxx }
this
.
form
=
{
...
response
.
data
};
}).
catch
(
error
=>
{
this
.
$message
.
error
(
"加载AD范围数据失败: "
+
(
error
.
message
||
"未知错误"
));
}).
finally
(()
=>
{
this
.
loading
=
false
;
});
},
/**
* 保存设置
*/
handleSave
()
{
this
.
$refs
[
"formRef"
].
validate
(
valid
=>
{
if
(
valid
)
{
this
.
loading
=
true
;
if
(
this
.
form
.
id
)
{
updateRange
(
this
.
form
).
then
(
response
=>
{
this
.
$message
.
success
(
"保存成功"
);
}).
catch
(
error
=>
{
this
.
$message
.
error
(
"保存失败: "
+
(
error
.
message
||
"未知错误"
));
}).
finally
(()
=>
{
this
.
loading
=
false
;
});
}
else
{
addRange
(
this
.
form
).
then
(
response
=>
{
this
.
form
.
id
=
response
.
data
;
this
.
$message
.
success
(
"保存成功"
);
}).
catch
(
error
=>
{
this
.
$message
.
error
(
"保存失败: "
+
(
error
.
message
||
"未知错误"
));
}).
finally
(()
=>
{
this
.
loading
=
false
;
});
}
}
});
},
}
};
</
script
>
<
style
scoped
>
.el-card
{
border-radius
:
12px
;
border
:
1px
solid
#ebeef5
;
}
.el-card__header
{
background-color
:
#f5f7fa
;
border-bottom
:
1px
solid
#ebeef5
;
}
.el-form-item
{
margin-bottom
:
20px
;
}
.w-80
{
width
:
240px
;
}
.mt-4
{
margin-top
:
16px
;
}
</
style
>
zhmes-agecal-web/src/views/realAdRange/oldIndex.vue
0 → 100644
View file @
debf3249
<
template
>
<div
class=
"app-container"
>
<el-form
:model=
"queryParams"
ref=
"queryForm"
:inline=
"true"
v-show=
"showSearch"
label-width=
"68px"
>
<el-form-item
label=
"实时AD最小值"
prop=
"realTimeAdMin"
>
<el-input
v-model=
"queryParams.realTimeAdMin"
placeholder=
"请输入实时AD最小值"
clearable
size=
"small"
@
keyup
.
enter
.
native=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"实时AD最大值"
prop=
"realTimeAdMax"
>
<el-input
v-model=
"queryParams.realTimeAdMax"
placeholder=
"请输入实时AD最大值"
clearable
size=
"small"
@
keyup
.
enter
.
native=
"handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
icon=
"el-icon-search"
size=
"mini"
@
click=
"handleQuery"
>
搜索
</el-button>
<el-button
icon=
"el-icon-refresh"
size=
"mini"
@
click=
"resetQuery"
>
重置
</el-button>
</el-form-item>
</el-form>
<el-row
:gutter=
"10"
class=
"mb8"
>
<el-col
:span=
"1.5"
>
<el-button
type=
"primary"
plain
icon=
"el-icon-plus"
size=
"mini"
@
click=
"handleAdd"
v-hasPermi=
"['system:range:add']"
>
新增
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"success"
plain
icon=
"el-icon-edit"
size=
"mini"
:disabled=
"single"
@
click=
"handleUpdate"
v-hasPermi=
"['system:range:edit']"
>
修改
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"danger"
plain
icon=
"el-icon-delete"
size=
"mini"
:disabled=
"multiple"
@
click=
"handleDelete"
v-hasPermi=
"['system:range:remove']"
>
删除
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"warning"
plain
icon=
"el-icon-download"
size=
"mini"
:loading=
"exportLoading"
@
click=
"handleExport"
v-hasPermi=
"['system:range:export']"
>
导出
</el-button>
</el-col>
<right-toolbar
:showSearch
.
sync=
"showSearch"
@
queryTable=
"getList"
></right-toolbar>
</el-row>
<el-table
v-loading=
"loading"
:data=
"rangeList"
@
selection-change=
"handleSelectionChange"
>
<el-table-column
type=
"selection"
width=
"55"
align=
"center"
/>
<el-table-column
label=
"主键ID"
align=
"center"
prop=
"id"
/>
<el-table-column
label=
"实时AD最小值"
align=
"center"
prop=
"realTimeAdMin"
/>
<el-table-column
label=
"实时AD最大值"
align=
"center"
prop=
"realTimeAdMax"
/>
<el-table-column
label=
"操作"
align=
"center"
class-name=
"small-padding fixed-width"
>
<template
slot-scope=
"scope"
>
<el-button
size=
"mini"
type=
"text"
icon=
"el-icon-edit"
@
click=
"handleUpdate(scope.row)"
v-hasPermi=
"['system:range:edit']"
>
修改
</el-button>
<el-button
size=
"mini"
type=
"text"
icon=
"el-icon-delete"
@
click=
"handleDelete(scope.row)"
v-hasPermi=
"['system:range:remove']"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
<pagination
v-show=
"total>0"
:total=
"total"
:page
.
sync=
"queryParams.pageNum"
:limit
.
sync=
"queryParams.pageSize"
@
pagination=
"getList"
/>
<!-- 添加或修改实时AD范围维护对话框 -->
<el-dialog
:title=
"title"
:visible
.
sync=
"open"
width=
"500px"
append-to-body
>
<el-form
ref=
"form"
:model=
"form"
:rules=
"rules"
label-width=
"80px"
>
<el-form-item
label=
"实时AD最小值"
prop=
"realTimeAdMin"
>
<el-input
v-model=
"form.realTimeAdMin"
placeholder=
"请输入实时AD最小值"
/>
</el-form-item>
<el-form-item
label=
"实时AD最大值"
prop=
"realTimeAdMax"
>
<el-input
v-model=
"form.realTimeAdMax"
placeholder=
"请输入实时AD最大值"
/>
</el-form-item>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
type=
"primary"
@
click=
"submitForm"
>
确 定
</el-button>
<el-button
@
click=
"cancel"
>
取 消
</el-button>
</div>
</el-dialog>
</div>
</template>
<
script
>
import
{
listRange
,
getRange
,
delRange
,
addRange
,
updateRange
,
exportRange
}
from
"@/api/realAdRange/realAdRange"
;
export
default
{
name
:
"Range"
,
components
:
{
},
data
()
{
return
{
// 遮罩层
loading
:
true
,
// 导出遮罩层
exportLoading
:
false
,
// 选中数组
ids
:
[],
// 非单个禁用
single
:
true
,
// 非多个禁用
multiple
:
true
,
// 显示搜索条件
showSearch
:
true
,
// 总条数
total
:
0
,
// 实时AD范围维护表格数据
rangeList
:
[],
// 弹出层标题
title
:
""
,
// 是否显示弹出层
open
:
false
,
// 查询参数
queryParams
:
{
pageNum
:
1
,
pageSize
:
10
,
realTimeAdMin
:
null
,
realTimeAdMax
:
null
},
// 表单参数
form
:
{},
// 表单校验
rules
:
{
realTimeAdMin
:
[
{
required
:
true
,
message
:
"实时AD最小值不能为空"
,
trigger
:
"blur"
}
],
realTimeAdMax
:
[
{
required
:
true
,
message
:
"实时AD最大值不能为空"
,
trigger
:
"blur"
}
]
}
};
},
created
()
{
this
.
getList
();
},
methods
:
{
/** 查询实时AD范围维护列表 */
getList
()
{
this
.
loading
=
true
;
listRange
(
this
.
queryParams
).
then
(
response
=>
{
this
.
rangeList
=
response
.
rows
;
this
.
total
=
response
.
total
;
this
.
loading
=
false
;
});
},
// 取消按钮
cancel
()
{
this
.
open
=
false
;
this
.
reset
();
},
// 表单重置
reset
()
{
this
.
form
=
{
id
:
null
,
realTimeAdMin
:
null
,
realTimeAdMax
:
null
};
this
.
resetForm
(
"form"
);
},
/** 搜索按钮操作 */
handleQuery
()
{
this
.
queryParams
.
pageNum
=
1
;
this
.
getList
();
},
/** 重置按钮操作 */
resetQuery
()
{
this
.
resetForm
(
"queryForm"
);
this
.
handleQuery
();
},
// 多选框选中数据
handleSelectionChange
(
selection
)
{
this
.
ids
=
selection
.
map
(
item
=>
item
.
id
)
this
.
single
=
selection
.
length
!==
1
this
.
multiple
=
!
selection
.
length
},
/** 新增按钮操作 */
handleAdd
()
{
this
.
reset
();
this
.
open
=
true
;
this
.
title
=
"添加实时AD范围维护"
;
},
/** 修改按钮操作 */
handleUpdate
(
row
)
{
this
.
reset
();
const
id
=
row
.
id
||
this
.
ids
getRange
(
id
).
then
(
response
=>
{
this
.
form
=
response
.
data
;
this
.
open
=
true
;
this
.
title
=
"修改实时AD范围维护"
;
});
},
/** 提交按钮 */
submitForm
()
{
this
.
$refs
[
"form"
].
validate
(
valid
=>
{
if
(
valid
)
{
if
(
this
.
form
.
id
!=
null
)
{
updateRange
(
this
.
form
).
then
(
response
=>
{
this
.
msgSuccess
(
"修改成功"
);
this
.
open
=
false
;
this
.
getList
();
});
}
else
{
addRange
(
this
.
form
).
then
(
response
=>
{
this
.
msgSuccess
(
"新增成功"
);
this
.
open
=
false
;
this
.
getList
();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete
(
row
)
{
const
ids
=
row
.
id
||
this
.
ids
;
this
.
$confirm
(
'是否确认删除实时AD范围维护编号为"'
+
ids
+
'"的数据项?'
,
"警告"
,
{
confirmButtonText
:
"确定"
,
cancelButtonText
:
"取消"
,
type
:
"warning"
}).
then
(
function
()
{
return
delRange
(
ids
);
}).
then
(()
=>
{
this
.
getList
();
this
.
msgSuccess
(
"删除成功"
);
}).
catch
(()
=>
{});
},
/** 导出按钮操作 */
handleExport
()
{
const
queryParams
=
this
.
queryParams
;
this
.
$confirm
(
'是否确认导出所有实时AD范围维护数据项?'
,
"警告"
,
{
confirmButtonText
:
"确定"
,
cancelButtonText
:
"取消"
,
type
:
"warning"
}).
then
(()
=>
{
this
.
exportLoading
=
true
;
return
exportRange
(
queryParams
);
}).
then
(
response
=>
{
this
.
download
(
response
.
msg
);
this
.
exportLoading
=
false
;
}).
catch
(()
=>
{});
}
}
};
</
script
>
zhmes-agecal-web/src/views/screen/components/RealTimeData.vue
View file @
debf3249
...
...
@@ -63,12 +63,16 @@
<div
class=
"device-code"
>
{{
scope
.
row
.
deviceCode
}}
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"行"
prop=
"row"
align=
"center"
width=
"80"
/>
<el-table-column
label=
"列"
prop=
"col"
align=
"center"
width=
"80"
/>
<el-table-column
label=
"位置编号"
prop=
"number"
align=
"center"
width=
"150"
/>
<!-- <el-table-column label="行" prop="row" align="center" width="80" />-->
<!-- <el-table-column label="列" prop="col" align="center" width="80" />-->
<el-table-column
label=
"位置编号"
prop=
"number"
align=
"center"
width=
"120"
>
<
template
slot-scope=
"scope"
>
<div
class=
"device-code"
>
{{
scope
.
row
.
number
}}
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"绑定时间"
align=
"center"
width=
"150"
>
<
template
slot-scope=
"scope"
>
<div
class=
"
binding-tim
e"
>
{{
scope
.
row
.
bindingTime
?
formatDate
(
scope
.
row
.
bindingTime
)
:
'-'
}}
</div>
<div
class=
"
device-cod
e"
>
{{
scope
.
row
.
bindingTime
?
formatDate
(
scope
.
row
.
bindingTime
)
:
'-'
}}
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"状态"
align=
"center"
width=
"120"
>
...
...
@@ -82,51 +86,71 @@
</el-tag>
</
template
>
</el-table-column>
<el-table-column
label=
"
浓度"
prop=
"concentration"
align=
"center"
width=
"10
0"
>
<el-table-column
label=
"
写时间状态"
align=
"center"
width=
"15
0"
>
<
template
slot-scope=
"scope"
>
<div
class=
"concentration"
>
{{
scope
.
row
.
concentration
||
'-'
}}
</div>
<span
v-if=
"scope.row.writeTimeStatus === '1'"
class=
"write-success"
>
成功
</span>
<span
v-if=
"scope.row.writeTimeStatus === '0'"
class=
"write-failed"
>
失败
</span>
<span
v-else
class=
"write-unknown"
>
-
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"
写时间状态"
align=
"center"
width=
"12
0"
>
<el-table-column
label=
"
时间运行状态"
align=
"center"
width=
"15
0"
>
<
template
slot-scope=
"scope"
>
<span
v-if=
"scope.row.
write
TimeStatus === '1'"
class=
"write-success"
>
成功
</span>
<span
v-if=
"scope.row.
write
TimeStatus === '0'"
class=
"write-failed"
>
失败
</span>
<span
v-if=
"scope.row.
run
TimeStatus === '1'"
class=
"write-success"
>
成功
</span>
<span
v-if=
"scope.row.
run
TimeStatus === '0'"
class=
"write-failed"
>
失败
</span>
<span
v-else
class=
"write-unknown"
>
-
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"
零点校准AD"
align=
"center"
width=
"12
0"
>
<el-table-column
label=
"
浓度"
prop=
"concentration"
align=
"center"
width=
"10
0"
>
<
template
slot-scope=
"scope"
>
<div
class=
"adjustment-zero"
>
{{
scope
.
row
.
adjustmentZeroAd
||
'-'
}}
</div>
<div
class=
"device-code"
>
{{
scope
.
row
.
concentration
||
'-'
}}
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"零点AD"
align=
"center"
width=
"150"
>
<
template
slot-scope=
"scope"
>
<div
class=
"device-code"
>
{{
scope
.
row
.
adjustmentZeroAd
||
'-'
}}
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"校准AD"
align=
"center"
width=
"120"
>
<
template
slot-scope=
"scope"
>
<div
class=
"calibration-ad"
>
{{
scope
.
row
.
calibrationAd
||
'-'
}}
</div>
<div
class=
"device-code"
>
{{
scope
.
row
.
calibrationAd
||
'-'
}}
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"实时AD"
align=
"center"
width=
"120"
>
<
template
slot-scope=
"scope"
>
<div
class=
"device-code"
>
{{
scope
.
row
.
realTimeAd
||
'-'
}}
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"实时AD状态"
align=
"center"
width=
"150"
>
<
template
slot-scope=
"scope"
>
<span
v-if=
"scope.row.realTimeStatus === '1'"
class=
"write-success"
>
正常
</span>
<span
v-if=
"scope.row.realTimeStatus === '0'"
class=
"write-failed"
>
异常
</span>
<span
v-else
class=
"write-unknown"
>
-
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"通信年"
prop=
"recordYear"
align=
"center"
width=
"100"
>
<
template
slot-scope=
"scope"
>
<div
class=
"
record-year
"
>
{{
scope
.
row
.
recordYear
||
'-'
}}
</div>
<div
class=
"
device-code
"
>
{{
scope
.
row
.
recordYear
||
'-'
}}
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"通信月"
prop=
"recordMonth"
align=
"center"
width=
"100"
>
<
template
slot-scope=
"scope"
>
<div
class=
"
record-month
"
>
{{
scope
.
row
.
recordMonth
||
'-'
}}
</div>
<div
class=
"
device-code
"
>
{{
scope
.
row
.
recordMonth
||
'-'
}}
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"通信日"
prop=
"recordDate"
align=
"center"
width=
"100"
>
<
template
slot-scope=
"scope"
>
<div
class=
"
record-dat
e"
>
{{
scope
.
row
.
recordDate
||
'-'
}}
</div>
<div
class=
"
device-cod
e"
>
{{
scope
.
row
.
recordDate
||
'-'
}}
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"通信时"
prop=
"recordHour"
align=
"center"
width=
"100"
>
<
template
slot-scope=
"scope"
>
<div
class=
"
record-hour
"
>
{{
scope
.
row
.
recordHour
||
'-'
}}
</div>
<div
class=
"
device-code
"
>
{{
scope
.
row
.
recordHour
||
'-'
}}
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"通信分"
prop=
"recordMinute"
align=
"center"
width=
"100"
>
<
template
slot-scope=
"scope"
>
<div
class=
"
record-minut
e"
>
{{
scope
.
row
.
recordMinute
||
'-'
}}
</div>
<div
class=
"
device-cod
e"
>
{{
scope
.
row
.
recordMinute
||
'-'
}}
</div>
</
template
>
</el-table-column>
</el-table>
...
...
zhmes-agecal-web/src/views/storey/index.vue
View file @
debf3249
...
...
@@ -113,18 +113,18 @@
<
el
-
table
-
column
label
=
"上料指令"
align
=
"center"
prop
=
"feedingCommand"
/>
<
el
-
table
-
column
label
=
"操作"
align
=
"center"
class
-
name
=
"small-padding fixed-width"
>
<
template
slot
-
scope
=
"scope"
>
<
el
-
button
size
=
"mini"
type
=
"text"
icon
=
"el-icon-edit"
@
click
=
"handleUpdate(scope.row)"
>
修改
<
/el-button
>
<
el
-
button
size
=
"mini"
type
=
"text"
icon
=
"el-icon-delete"
@
click
=
"handleDelete(scope.row)"
>
删除
<
/el-button
>
<!--
<
el
-
button
-->
<!--
size
=
"mini"
-->
<!--
type
=
"text"
-->
<!--
icon
=
"el-icon-edit"
-->
<!--
@
click
=
"handleUpdate(scope.row)"
-->
<!--
>
修改
<
/el-button>--
>
<!--
<
el
-
button
-->
<!--
size
=
"mini"
-->
<!--
type
=
"text"
-->
<!--
icon
=
"el-icon-delete"
-->
<!--
@
click
=
"handleDelete(scope.row)"
-->
<!--
>
删除
<
/el-button>--
>
<
el
-
button
size
=
"mini"
type
=
"text"
...
...
@@ -146,12 +146,18 @@
size
=
"mini"
type
=
"text"
@
click
=
"handleBlanking(scope.row)"
>
生成下料命令
<
/el-button
>
>
下料
<
/el-button
>
<
el
-
button
size
=
"mini"
type
=
"text"
@
click
=
"handleDirectBlanking(scope.row)"
>
直接下料
<
/el-button
>
@
click
=
"handleReAgine(scope.row)"
>
重新老化
<
/el-button
>
<!--
<
el
-
button
-->
<!--
size
=
"mini"
-->
<!--
type
=
"text"
-->
<!--
@
click
=
"handleDirectBlanking(scope.row)"
-->
<!--
>
直接下料
<
/el-button>--
>
<
/template
>
<
/el-table-column
>
<
/el-table
>
...
...
@@ -216,7 +222,7 @@
import
{
listStorey
,
getStorey
,
delStorey
,
addStorey
,
updateStorey
,
exportStorey
,
PowerOn
,
PowerOutage
,
feeding
,
blanking
,
directBlanking
feeding
,
blanking
,
directBlanking
,
reAgine
}
from
"@/api/storey/storey"
;
import
{
sendHomeCommand
,
sendStopCommand
}
from
"@/api/robotArm/robotArmCommand"
;
...
...
@@ -410,6 +416,20 @@ export default {
this
.
msgSuccess
(
"下料成功"
);
}
).
catch
(()
=>
{
}
);
}
,
/** 重新老化 */
handleReAgine
(
row
)
{
const
fIp
=
row
.
fIp
;
this
.
$confirm
(
'是否确认重新老化IP为"'
+
fIp
+
'"的设备?'
,
"警告"
,
{
confirmButtonText
:
"确定"
,
cancelButtonText
:
"取消"
,
type
:
"warning"
}
).
then
(
function
()
{
return
reAgine
(
row
);
}
).
then
(()
=>
{
this
.
getList
();
this
.
msgSuccess
(
"重新老化开始"
);
}
).
catch
(()
=>
{
}
);
}
,
// 下料
handleBlanking
(
row
)
{
const
fIp
=
row
.
fIp
;
...
...
zhmes-agecal-web/src/views/uploadMesAddress/index.vue
0 → 100644
View file @
debf3249
<
template
>
<div
class=
"app-container"
>
<el-card
shadow=
"hover"
style=
"max-width: 1000px; margin: 0 auto;"
>
<div
slot=
"header"
class=
"clearfix"
>
<span>
上传MES地址维护
</span>
</div>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"rules"
label-width=
"120px"
class=
"mt-4"
>
<el-form-item
label=
"MES地址"
prop=
"mesAddress"
>
<el-input
v-model=
"form.msg"
placeholder=
"请输入上传MES地址"
style=
"width:700px"
/>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
@
click=
"handleSave"
:loading=
"loading"
>
<i
class=
"el-icon-check"
></i>
保存设置
</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</
template
>
<
script
>
import
{
getUploadMesAddress
,
updateUploadMesAddress
}
from
"@/api/system/config"
;
export
default
{
name
:
"MesAddressConfig"
,
data
()
{
return
{
// 加载状态
loading
:
false
,
// 表单数据
form
:
{
msg
:
""
},
// 表单校验规则
rules
:
{
msg
:
[
{
required
:
true
,
message
:
"MES地址不能为空"
,
trigger
:
"blur"
},
{
validator
:
(
rule
,
value
,
callback
)
=>
{
if
(
value
&&
!
this
.
isValidUrl
(
value
))
{
callback
(
new
Error
(
"请输入有效的URL地址"
));
}
else
{
callback
();
}
},
trigger
:
"blur"
}
]
}
};
},
created
()
{
// 初始化时加载数据
this
.
fetchData
();
},
methods
:
{
/**
* URL格式验证
*/
isValidUrl
(
url
)
{
try
{
new
URL
(
url
);
return
true
;
}
catch
(
e
)
{
return
false
;
}
},
/**
* 加载MES地址数据
*/
fetchData
()
{
this
.
loading
=
true
;
getUploadMesAddress
().
then
(
response
=>
{
if
(
response
.
msg
)
{
this
.
form
=
{
...
response
};
}
}).
catch
(
error
=>
{
this
.
$message
.
error
(
"加载MES地址失败: "
+
(
error
.
message
||
"未知错误"
));
}).
finally
(()
=>
{
this
.
loading
=
false
;
});
},
/**
* 保存设置
*/
handleSave
()
{
this
.
$refs
[
"formRef"
].
validate
(
valid
=>
{
if
(
valid
)
{
this
.
loading
=
true
;
let
obj
=
{
configValue
:
this
.
form
.
msg
};
updateUploadMesAddress
(
obj
).
then
(
response
=>
{
this
.
$message
.
success
(
"保存成功"
);
}).
catch
(
error
=>
{
this
.
$message
.
error
(
"保存失败: "
+
(
error
.
message
||
"未知错误"
));
}).
finally
(()
=>
{
this
.
loading
=
false
;
});
}
});
},
}
};
</
script
>
<
style
scoped
>
.el-card
{
border-radius
:
12px
;
border
:
1px
solid
#ebeef5
;
}
.el-card__header
{
background-color
:
#f5f7fa
;
border-bottom
:
1px
solid
#ebeef5
;
}
.el-form-item
{
margin-bottom
:
20px
;
}
.w-80
{
width
:
240px
;
}
.mt-4
{
margin-top
:
16px
;
}
</
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