diff --git a/src/main/java/com/techsor/datacenter/sender/dao/DashboardAlertDao.java b/src/main/java/com/techsor/datacenter/sender/dao/DashboardAlertDao.java index 32cd108..7a87095 100644 --- a/src/main/java/com/techsor/datacenter/sender/dao/DashboardAlertDao.java +++ b/src/main/java/com/techsor/datacenter/sender/dao/DashboardAlertDao.java @@ -9,6 +9,7 @@ import lombok.extern.slf4j.Slf4j; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Statement; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -19,6 +20,8 @@ import org.apache.commons.lang.StringUtils; import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; import org.springframework.stereotype.Component; import jakarta.annotation.Resource; @@ -150,16 +153,36 @@ public class DashboardAlertDao { public void insertAlertHistory(DynamodbEntity entity) { String sql = "INSERT INTO alert_history (" + - "device_id, receive_ts, retain_alert" + - ") VALUES (?, ?, ?)"; + "device_id, receive_ts, retain_alert" + + ") VALUES (?, ?, ?)"; jdbcTemplate.update(sql, - entity.getDeviceId(), - entity.getReceive_ts(), - entity.getRetainAlert() + entity.getDeviceId(), + entity.getReceive_ts(), + entity.getRetainAlert() ); } + public Long insertAlertHistory(DynamodbEntity entity, int sourceType) { + + String sql = "INSERT INTO alert_history (" + + "device_id, receive_ts, source_type" + + ") VALUES (?, ?, ?)"; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + jdbcTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); + ps.setString(1, entity.getDeviceId()); + ps.setLong(2, entity.getReceive_ts()); + ps.setInt(3, sourceType); + return ps; + }, keyHolder); + + // 获取主键ID + return keyHolder.getKey() != null ? keyHolder.getKey().longValue() : null; + } + public void updateLatestAlertToAutoRecovered(DynamodbEntity entity) { String sql = "SELECT * FROM alert_history WHERE device_id = ? ORDER BY id DESC LIMIT 1"; diff --git a/src/main/java/com/techsor/datacenter/sender/dao/F10Dao.java b/src/main/java/com/techsor/datacenter/sender/dao/F10Dao.java index 3d04a8f..b005dd8 100644 --- a/src/main/java/com/techsor/datacenter/sender/dao/F10Dao.java +++ b/src/main/java/com/techsor/datacenter/sender/dao/F10Dao.java @@ -12,7 +12,7 @@ public class F10Dao { private JdbcTemplate jdbcTemplate ; public void insertF10Log(F10JournalLog f10JournalLog) { - String sql = "INSERT INTO f10_journal_log (" + + String sql = "INSERT IGNORE INTO f10_journal_log (" + "device_id, company_id, raw_hex, raw_text, serial_no, mode, " + "signal_seq, receive_date, receive_time, channel_no, test_flag, block_no, block_name, " + "signal_type1, signal_type2, signal_label, signal_status, " + @@ -20,8 +20,8 @@ public class F10Dao { "customer_name, phone, remark, display_color, error_reason, line_type, area_name, " + "send_date, send_time, customer_no, display_data1, display_data2, " + "instruction_flag, signal_code, card_no, card_type, mansion_building, mansion_room, option_field, " + - "created_at, created_time" + - ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + "created_at, created_time, receive_timestamp, expired_flag, alert_history_id" + + ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; jdbcTemplate.update(sql, f10JournalLog.getDeviceId(), @@ -72,8 +72,11 @@ public class F10Dao { f10JournalLog.getMansionRoom(), f10JournalLog.getOptionField(), - System.currentTimeMillis(), - new java.sql.Timestamp(System.currentTimeMillis()) + f10JournalLog.getCreatedAt(), + new java.sql.Timestamp(f10JournalLog.getCreatedAt()), + f10JournalLog.getReceiveTimestamp(), + f10JournalLog.getExpiredFlag(), + f10JournalLog.getAlertHistoryId() ); } } diff --git a/src/main/java/com/techsor/datacenter/sender/entitiy/f10/F10JournalLog.java b/src/main/java/com/techsor/datacenter/sender/entitiy/f10/F10JournalLog.java index 80d8769..9a059fc 100644 --- a/src/main/java/com/techsor/datacenter/sender/entitiy/f10/F10JournalLog.java +++ b/src/main/java/com/techsor/datacenter/sender/entitiy/f10/F10JournalLog.java @@ -76,4 +76,12 @@ public class F10JournalLog { // ===== 系统字段 ===== private Long createdAt; // 毫秒时间戳 private LocalDateTime createdTime; // 标准时间 + + // 接收时间戳(JST) + private Long receiveTimestamp; + + // 是否过期告警(0=正常,1=过期) + private Integer expiredFlag; + + private Long alertHistoryId; } diff --git a/src/main/java/com/techsor/datacenter/sender/service/F10Service.java b/src/main/java/com/techsor/datacenter/sender/service/F10Service.java index 12f6a65..687fe23 100644 --- a/src/main/java/com/techsor/datacenter/sender/service/F10Service.java +++ b/src/main/java/com/techsor/datacenter/sender/service/F10Service.java @@ -4,19 +4,26 @@ import cn.hutool.core.collection.CollectionUtil; import com.techsor.datacenter.sender.components.CommonOpt; import com.techsor.datacenter.sender.components.GuavaRedisCache; import com.techsor.datacenter.sender.config.DataSourceContextHolder; +import com.techsor.datacenter.sender.dao.DashboardAlertDao; import com.techsor.datacenter.sender.dao.DeviceDao; import com.techsor.datacenter.sender.dao.F10Dao; import com.techsor.datacenter.sender.entitiy.DeviceEntity; +import com.techsor.datacenter.sender.entitiy.DynamodbEntity; import com.techsor.datacenter.sender.entitiy.f10.F10JournalLog; import com.techsor.datacenter.sender.entitiy.f10.RedisStreamEntity; +import com.techsor.datacenter.sender.utils.RedisUtils; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.nio.charset.Charset; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.Arrays; import java.util.List; +import java.util.concurrent.TimeUnit; @Slf4j @Service("F10Service") @@ -24,15 +31,21 @@ public class F10Service { private static final Charset SHIFT_JIS = Charset.forName("Shift-JIS"); + private static final ZoneId JST = ZoneId.of("Asia/Tokyo"); + @Autowired private CommonOpt commonOpt; @Resource private GuavaRedisCache guavaRedisCache; + @Resource + private RedisUtils redisUtils; @Autowired private F10Dao f10Dao; @Autowired private DeviceDao deviceDao; + @Autowired + private DashboardAlertDao dashboardAlertDao; @@ -46,12 +59,50 @@ public class F10Service { } try { + long currentTs = System.currentTimeMillis(); + F10JournalLog f10JournalLog = parseToEntity(rawEntity.getHexRawData()); + f10JournalLog.setCreatedAt(currentTs); //前缀_26契約先番号_4チャンネル番号 //前缀还没定,先【26契約先番号_4チャンネル番号】 f10JournalLog.setDeviceId(f10JournalLog.getCustomerNo() + "_" + f10JournalLog.getChannelNo()); + long receivedCurrentTs = parseToTimestamp(f10JournalLog.getReceiveDate(), f10JournalLog.getReceiveTime()); + f10JournalLog.setReceiveTimestamp(receivedCurrentTs); + + String redisKey = getLatestAlarmKey(f10JournalLog.getDeviceId()); + // 从 Redis 取值 + String latestTsStr = redisUtils.get(redisKey); + Long latestTs = null; + if (latestTsStr != null) { + try { + latestTs = Long.parseLong(latestTsStr); + } catch (Exception e) { + log.error("Redis数据异常,无法转换为Long: key={}, value={}", redisKey, latestTsStr); + } + } + + boolean isExpired = false; + // ===== 判断逻辑 ===== + if (latestTs == null) { + // 首次 + redisUtils.add(redisKey, String.valueOf(receivedCurrentTs)); + } else { + if (receivedCurrentTs > latestTs) { + // 新数据 + redisUtils.add(redisKey, String.valueOf(receivedCurrentTs)); + } else if (receivedCurrentTs == latestTs) { + // 重复数据 → 直接丢弃 + log.warn("重复告警,丢弃 deviceId={}", f10JournalLog.getDeviceId()); + return; + } else { + // 旧数据 → 标记过期 + isExpired = true; + } + } + f10JournalLog.setExpiredFlag(isExpired ? 1 : 0); + String topCompanyId= commonOpt.getTopCompanyId(f10JournalLog.getDeviceId()); if (topCompanyId==null || topCompanyId.equals("0")){ log.error("no companyId is found========================>>>> {}",f10JournalLog.getDeviceId()); @@ -69,8 +120,17 @@ public class F10Service { } Long companyId = deviceEntity.get(0).getCompanyId(); - f10JournalLog.setCompanyId(companyId); + + if (!isExpired){ + DynamodbEntity entity = new DynamodbEntity(); + entity.setDeviceId(f10JournalLog.getDeviceId()); + entity.setReceive_ts(currentTs); + Long dbId = dashboardAlertDao.insertAlertHistory(entity, 2); + f10JournalLog.setAlertHistoryId(dbId); + } + + f10Dao.insertF10Log(f10JournalLog); } catch (Exception e) { @@ -78,6 +138,10 @@ public class F10Service { } } + public static String getLatestAlarmKey(String deviceId) { + return "f10:latest_alarm:" + deviceId; + } + public static F10JournalLog parseToEntity(String hexLog) { byte[] src = hexStringToByteArray(hexLog); @@ -170,4 +234,13 @@ public class F10Service { return data; } + public static long parseToTimestamp(String date, String time) { + LocalDateTime ldt = LocalDateTime.parse( + date + time, + DateTimeFormatter.ofPattern("yyyyMMddHHmmss") + ); + + return ldt.atZone(JST).toInstant().toEpochMilli(); + } + }