package com.zksy.api.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.zksy.api.domain.AlarmData; import org.apache.ibatis.annotations.Options; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; public interface AlarmDataMapper extends BaseMapper { /** Kingbase事务锁:同一设备/报警编码的跨线程、跨实例写入串行,提交/回滚自动释放。 */ @Select("SELECT 1 FROM pg_advisory_xact_lock(hashtext('collection-alarm:' || #{deviceCode}), hashtext(#{warningCode}))") @Options(timeout = 5) Integer lockAlarmKey(@Param("deviceCode") String deviceCode, @Param("warningCode") String warningCode); /** 锁定最新未处理记录,防止读取等级后人工处理;独立语句保证看到前一写入事务的提交。 */ @Select("SELECT id, alarm_level FROM alarm_data WHERE device_code=#{deviceCode} AND warning_code=#{warningCode} AND alarm_status=0 " + "ORDER BY alarm_time DESC NULLS LAST, create_time DESC NULLS LAST, id DESC LIMIT 1 FOR UPDATE") @Options(timeout = 5) AlarmData selectUnhandledAlarmForUpdate(@Param("deviceCode") String deviceCode, @Param("warningCode") String warningCode); /** 只更新本次等级对应的采集字段;max_value非空列在无阈值时写0,其余空指标可清空。 */ @Update("UPDATE alarm_data SET alarm_level=#{sample.alarmLevel}, actual_value=#{sample.actualValue,jdbcType=NUMERIC}, " + "min_value=#{sample.minValue,jdbcType=NUMERIC}, max_value=COALESCE(#{sample.maxValue,jdbcType=NUMERIC},0), " + "deviation_ratio=#{sample.deviationRatio,jdbcType=NUMERIC}, update_time=CURRENT_TIMESTAMP " + "WHERE id=#{id} AND device_code=#{sample.deviceCode} AND warning_code=#{sample.warningCode} AND alarm_status=0") @Options(timeout = 5) int updateUnhandledAlarmLevel(@Param("id") String id, @Param("sample") AlarmData sample); /** 按指标恢复全部未处理记录(包括历史重复);保留告警发生时的等级、数值和工单关联。 */ @Update("UPDATE alarm_data SET alarm_status=1, update_time=CURRENT_TIMESTAMP " + "WHERE device_code=#{deviceCode} AND warning_code=#{warningCode} AND alarm_status=0") @Options(timeout = 5) int markUnhandledAlarmsRecovered(@Param("deviceCode") String deviceCode, @Param("warningCode") String warningCode); }