feat(production): 添加安灯派工时间记录和预警处理功能

- 在安灯派工状态变为已接单时自动设置接单时间
- 添加批量标记预警为已处理的接口和实现
- 实现预警去重机制,避免重复生成相同预警
- 添加预警冷却时间控制,5分钟内不重复生成
- 更新未处理预警时只更新数值和时间信息
- 添加安灯生产监控看板服务接口定义
master
zangch@mesnac.com 2 days ago
parent 7f1e4425bb
commit 6ed1d4492a

@ -94,4 +94,15 @@ public class ProcessAlertController extends BaseController {
int count = processAlertService.checkThresholdAlerts();
return success("检查完成,生成预警 " + count + " 条");
}
/**
*
*/
@PreAuthorize("@ss.hasPermi('base:processAlert:edit')")
@Log(title = "批量标记预警已处理", businessType = BusinessType.UPDATE)
@PutMapping("/batchMarkProcessed")
public AjaxResult batchMarkProcessed(@RequestBody Long[] alertIds) {
int count = processAlertService.batchMarkAsProcessed(alertIds, getUsername());
return success("成功标记 " + count + " 条预警为已处理");
}
}

@ -58,4 +58,22 @@ public interface ProcessAlertMapper {
* @return
*/
public int deleteProcessAlertByAlertIds(Long[] alertIds);
/**
*
*
* @param deviceCode
* @param paramCode
* @return
*/
public ProcessAlert selectUnhandledAlert(String deviceCode, String paramCode);
/**
*
*
* @param deviceCode
* @param paramCode
* @return
*/
public ProcessAlert selectLatestAlert(String deviceCode, String paramCode);
}

@ -23,4 +23,12 @@ public interface IProcessAlertService {
* @return
*/
public int checkThresholdAlerts();
/**
*
* @param alertIds ID
* @param handleUser
* @return
*/
public int batchMarkAsProcessed(Long[] alertIds, String handleUser);
}

@ -136,26 +136,60 @@ public class ProcessAlertServiceImpl implements IProcessAlertService {
}
if (alertType != null) {
// 生成预警记录
ProcessAlert alert = new ProcessAlert();
alert.setAlertCode("ALERT-" + sdf.format(now) + "-" + (alertCount + 1));
alert.setAlertType("参数超限");
alert.setAlertLevel(param.getAlertLevel() != null ? param.getAlertLevel() : "1");
alert.setDeviceCode(param.getDeviceCode());
alert.setDeviceName(param.getDeviceName());
alert.setParamCode(param.getParamCode());
alert.setParamName(param.getParamName());
alert.setAlertContent(param.getParamName() + alertType + ",当前值:" + paramValueStr + ",阈值:" + thresholdValue);
alert.setAlertValue(paramValueStr);
alert.setThresholdValue(thresholdValue);
alert.setAlertTime(latestVal.getCollectTime() != null ? latestVal.getCollectTime() : now);
alert.setAlertStatus("0");
alert.setIsFlag("1");
alert.setCreateTime(now);
// 检查是否已存在未处理的预警(去重)
ProcessAlert existingAlert = processAlertMapper.selectUnhandledAlert(
param.getDeviceCode(),
param.getParamCode()
);
insertProcessAlert(alert);
alertCount++;
log.info("生成预警: {}", alert.getAlertContent());
if (existingAlert != null) {
// 已存在未处理的预警,更新预警值和时间
existingAlert.setAlertValue(paramValueStr);
existingAlert.setAlertTime(latestVal.getCollectTime() != null ? latestVal.getCollectTime() : now);
existingAlert.setAlertContent(param.getParamName() + alertType + ",当前值:" + paramValueStr + ",阈值:" + thresholdValue);
updateProcessAlert(existingAlert);
log.info("更新未处理预警: {}", existingAlert.getAlertContent());
} else {
// 查询最新预警(包含已处理)
ProcessAlert latestAlert = processAlertMapper.selectLatestAlert(
param.getDeviceCode(),
param.getParamCode()
);
// 如果存在已处理的预警检查预警冷却时间5分钟
if (latestAlert != null && "2".equals(latestAlert.getAlertStatus())) {
long timeDiff = now.getTime() - latestAlert.getAlertTime().getTime();
long cooldownMinutes = 5; // 预警冷却时间5分钟
if (timeDiff < cooldownMinutes * 60 * 1000) {
// 还在冷却期内,不生成新预警
log.debug("预警冷却期内,跳过: deviceCode={}, paramCode={}",
param.getDeviceCode(), param.getParamCode());
continue;
}
}
// 生成新的预警记录
ProcessAlert alert = new ProcessAlert();
alert.setAlertCode("ALERT-" + sdf.format(now) + "-" + (alertCount + 1));
alert.setAlertType("参数超限");
alert.setAlertLevel(param.getAlertLevel() != null ? param.getAlertLevel() : "1");
alert.setDeviceCode(param.getDeviceCode());
alert.setDeviceName(param.getDeviceName());
alert.setParamCode(param.getParamCode());
alert.setParamName(param.getParamName());
alert.setAlertContent(param.getParamName() + alertType + ",当前值:" + paramValueStr + ",阈值:" + thresholdValue);
alert.setAlertValue(paramValueStr);
alert.setThresholdValue(thresholdValue);
alert.setAlertTime(latestVal.getCollectTime() != null ? latestVal.getCollectTime() : now);
alert.setAlertStatus("0");
alert.setIsFlag("1");
alert.setCreateTime(now);
insertProcessAlert(alert);
alertCount++;
log.info("生成新预警: {}", alert.getAlertContent());
}
}
} catch (NumberFormatException e) {
log.warn("参数值无法转换为数字: paramCode={}, value={}", param.getParamCode(), paramValueStr);
@ -167,4 +201,33 @@ public class ProcessAlertServiceImpl implements IProcessAlertService {
return alertCount;
}
@Override
public int batchMarkAsProcessed(Long[] alertIds, String handleUser) {
if (alertIds == null || alertIds.length == 0) {
return 0;
}
int count = 0;
Date now = DateUtils.getNowDate();
for (Long alertId : alertIds) {
try {
ProcessAlert alert = processAlertMapper.selectProcessAlertByAlertId(alertId);
if (alert != null && !"2".equals(alert.getAlertStatus())) {
alert.setAlertStatus("2"); // 已处理
alert.setHandleUser(handleUser);
alert.setHandleTime(now);
alert.setHandleResult("批量标记为已处理");
processAlertMapper.updateProcessAlert(alert);
count++;
log.info("批量标记预警已处理: alertId={}, alertCode={}", alertId, alert.getAlertCode());
}
} catch (Exception e) {
log.error("标记预警已处理失败: alertId={}", alertId, e);
}
}
return count;
}
}

@ -149,4 +149,25 @@
#{alertId}
</foreach>
</delete>
<!-- 查询指定设备和参数的未处理预警 -->
<select id="selectUnhandledAlert" resultMap="ProcessAlertResult">
<include refid="selectProcessAlertVo"/>
where device_code = #{deviceCode}
and param_code = #{paramCode}
and alert_status = '0'
and is_flag = '1'
order by alert_time desc
fetch first 1 rows only
</select>
<!-- 查询指定设备和参数的最新预警 -->
<select id="selectLatestAlert" resultMap="ProcessAlertResult">
<include refid="selectProcessAlertVo"/>
where device_code = #{deviceCode}
and param_code = #{paramCode}
and is_flag = '1'
order by alert_time desc
fetch first 1 rows only
</select>
</mapper>

@ -0,0 +1,68 @@
package com.aucma.production.service;
import com.aucma.production.domain.dto.AndonDashboardDTO;
/**
* Service
*
* @author Yinq
* @date 2025-12-30
*/
public interface IAndonDashboardService {
/**
*
*
* @param productLineCode 线
* @return
*/
AndonDashboardDTO getDashboardData(String productLineCode);
/**
*
*
* @param productLineCode 线
* @return
*/
AndonDashboardDTO.DeviceStatusSummary getDeviceStatusSummary(String productLineCode);
/**
*
*
* @param productLineCode 线
* @return
*/
AndonDashboardDTO.TaskCompletionSummary getTaskCompletionSummary(String productLineCode);
/**
* OEE
*
* @param productLineCode 线
* @return OEE
*/
AndonDashboardDTO.OeeSummary getOeeSummary(String productLineCode);
/**
*
*
* @param productLineCode 线
* @return
*/
AndonDashboardDTO.UtilizationSummary getUtilizationSummary(String productLineCode);
/**
*
*
* @param productLineCode 线
* @return
*/
AndonDashboardDTO.QualitySummary getQualitySummary(String productLineCode);
/**
*
*
* @param productLineCode 线
* @return
*/
AndonDashboardDTO.AndonEventSummary getAndonEventSummary(String productLineCode);
}

@ -88,7 +88,11 @@ public class AndonEventAssignmentServiceImpl implements IAndonEventAssignmentSer
// 根据状态补充派工自身的里程碑时间
if (andonEventAssignment.getStatus() != null) {
String status = andonEventAssignment.getStatus();
// 当状态变为DONE时设置finishTime为当前时间安灯事件结束
// 当状态变为已接单时,自动设置接单时间
if (AnDonConstants.AssignmentStatus.ACCEPTED.equals(status) && andonEventAssignment.getAcceptTime() == null) {
andonEventAssignment.setAcceptTime(DateUtils.getNowDate());
}
// 当状态变为已完成时,自动设置完成时间
if (AnDonConstants.AssignmentStatus.DONE.equals(status) && andonEventAssignment.getFinishTime() == null) {
andonEventAssignment.setFinishTime(DateUtils.getNowDate());
}

Loading…
Cancel
Save