whyclxw
2025-02-05 4b659a6ece105f30debf0def9225b9a89c43bcd4
告警实时推送和告警历史查询
3个文件已修改
9个文件已添加
523 ■■■■■ 已修改文件
src/main/java/com/whyc/controller/LockAlarmController.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/controller/LockAlarmHisController.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/dto/LockAlmDto.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/mapper/LockAlarmMapper.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/pojo/db_lock_alarm/LockAlarm.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/pojo/db_lock_alarm/LockAlarmHis.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/service/LockAlarmHisService.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/service/LockAlarmService.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/service/LockHisService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/service/SubTableService.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/util/SubTablePageInfoUtil.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/webSocket/LockAlmRtSocket.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/controller/LockAlarmController.java
New file
@@ -0,0 +1,29 @@
package com.whyc.controller;
import com.whyc.dto.Response;
import com.whyc.service.LockAlarmService;
import com.whyc.service.LockHisService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.text.ParseException;
@RestController
@Api(tags = "告警管理")
@RequestMapping("lockAlm")
public class LockAlarmController {
    @Autowired
    private LockAlarmService service;
    @ApiOperation("查询锁实时告警信息")
    @GetMapping("getLockAlm")
    public Response getLockAlm(@RequestParam(required = false) Integer lockId, @RequestParam(required = false) Integer almId
            , @RequestParam int pageNum, @RequestParam int pageSize) {
        Response res=service.getLockAlm(lockId,almId,pageNum,pageSize);
        return res;
    }
}
src/main/java/com/whyc/controller/LockAlarmHisController.java
New file
@@ -0,0 +1,29 @@
package com.whyc.controller;
import com.whyc.dto.Response;
import com.whyc.service.LockAlarmHisService;
import com.whyc.service.LockHisService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.text.ParseException;
@RestController
@Api(tags = "告警历史管理")
@RequestMapping("lockAlmHis")
public class LockAlarmHisController {
    @Autowired
    private LockAlarmHisService service;
    @ApiOperation("查询锁告警的历史状态")
    @GetMapping("getLockAlmHis")
    public Response getLockAlmHis(@RequestParam Integer lockId,@RequestParam Integer almId, @RequestParam String startTime, @RequestParam String endTime
            , @RequestParam int pageNum, @RequestParam int pageSize) throws ParseException, InterruptedException {
        Response res=service.getLockAlmHis(lockId,almId,startTime,endTime,pageNum,pageSize);
        return res;
    }
}
src/main/java/com/whyc/dto/LockAlmDto.java
New file
@@ -0,0 +1,11 @@
package com.whyc.dto;
import lombok.Data;
@Data
public class LockAlmDto {
    private Integer lockId;
    private Integer almId;
    private Integer pageNum;
    private Integer pageSize;
}
src/main/java/com/whyc/mapper/LockAlarmMapper.java
New file
@@ -0,0 +1,6 @@
package com.whyc.mapper;
import com.whyc.pojo.db_lock_alarm.LockAlarm;
public interface LockAlarmMapper extends CustomMapper<LockAlarm>{
}
src/main/java/com/whyc/pojo/db_lock_alarm/LockAlarm.java
New file
@@ -0,0 +1,58 @@
package com.whyc.pojo.db_lock_alarm;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
 * <p>
 * 电子锁具实时告警表
 * </p>
 *
 * @author lxw
 * @since 2025-02-05
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName(schema = "db_lock_alarm",value = "tb_lock_alarm")
@ApiModel(value="LockAlarm对象", description="电子锁具实时告警表")
public class LockAlarm implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "自增主键")
    @TableId(value = "num", type = IdType.AUTO)
    private Integer num;
    @ApiModelProperty(value = "锁具ID")
    private Integer lockId;
    @ApiModelProperty(value = "告警类型[ 119001-通信故障  119002-开锁失败]")
    private Integer almId;
    @ApiModelProperty(value = "告警来源[1-平台触发  2-手机APP触发  3-锁具触发]")
    private Integer almSource;
    @ApiModelProperty(value = "告警开始时间")
    private Date almStartTime;
    @ApiModelProperty(value = "告警是否确认")
    private Integer almIsConfirmed;
    @ApiModelProperty(value = "告警确认时间")
    private Date almConfirmedTime;
    @ApiModelProperty(value = "告警结束时间")
    private Date almEndTime;
}
src/main/java/com/whyc/pojo/db_lock_alarm/LockAlarmHis.java
New file
@@ -0,0 +1,79 @@
package com.whyc.pojo.db_lock_alarm;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
 * <p>
 * 2025年电子锁具历史告警表
 * </p>
 *
 * @author lxw
 * @since 2025-02-05
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="LockAlarmHis对象", description="2025年电子锁具历史告警表")
public class LockAlarmHis implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "自增主键")
    @TableId(value = "num", type = IdType.AUTO)
    private Integer num;
    @ApiModelProperty(value = "锁具ID")
    private Integer lockId;
    @ApiModelProperty(value = "告警类型")
    private Integer almId;
    @ApiModelProperty(value = "告警来源[1-平台触发  2-手机APP触发  3-锁具触发]")
    private Integer almSource;
    @ApiModelProperty(value = "告警开始时间")
    private Date almStartTime;
    @ApiModelProperty(value = "告警是否确认")
    private Integer almIsConfirmed;
    @ApiModelProperty(value = "告警确认时间")
    private Date almConfirmedTime;
    @ApiModelProperty(value = "告警结束时间")
    private Date almEndTime;
    @TableField(exist = false)
    @ApiModelProperty("表名字拼接")
    private String recordYear;
    @TableField(exist = false)
    @ApiModelProperty("分页开始位置")
    private Integer limitStart;
    @TableField(exist = false)
    @ApiModelProperty("分页结束位置")
    private Integer limitEnd;
    @TableField(exist = false)
    @ApiModelProperty("开始时间")
    private Date startTime;
    @TableField(exist = false)
    @ApiModelProperty("结束时间")
    private Date endTime;
}
src/main/java/com/whyc/service/LockAlarmHisService.java
New file
@@ -0,0 +1,28 @@
package com.whyc.service;
import com.github.pagehelper.PageInfo;
import com.whyc.dto.Response;
import com.whyc.pojo.db_lock_alarm.LockAlarmHis;
import com.whyc.pojo.db_lock_his.LockHis;
import com.whyc.util.SubTablePageInfoUtil;
import com.whyc.util.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.ParseException;
@Service
public class LockAlarmHisService {
    @Autowired
    private SubTablePageInfoUtil util;
    //查询锁告警的历史状态
    public Response getLockAlmHis(Integer lockId, Integer almId,String startTime, String endTime, int pageNum, int pageSize) throws ParseException {
        LockAlarmHis his=new LockAlarmHis();
        his.setLockId(lockId);
        his.setAlmId(almId);
        PageInfo pageInfo=util.getPageInfo(pageNum,pageSize, ThreadLocalUtil.parse(startTime,1),ThreadLocalUtil.parse(endTime,1)
                ,"db_lock_alarm","tb_lock_alarm_",his);
        return new Response().setII(1,pageInfo.getList()!=null,pageInfo,"查询锁告警的历史状态");
    }
}
src/main/java/com/whyc/service/LockAlarmService.java
New file
@@ -0,0 +1,33 @@
package com.whyc.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.whyc.dto.Response;
import com.whyc.mapper.LockAlarmMapper;
import com.whyc.pojo.db_lock_alarm.LockAlarm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@Service
public class LockAlarmService {
    @Autowired(required = false)
    private LockAlarmMapper mapper;
    //查询锁实时告警信息
    public Response getLockAlm(Integer lockId, Integer almId,int pageNum,  int pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        QueryWrapper wrapper=new QueryWrapper();
        if(lockId!=null){
            wrapper.eq("lock_id",lockId);
        }
        if(almId!=null){
            wrapper.eq("alm_id",almId);
        }
        List<LockAlarm> list=mapper.selectList(wrapper);
        PageInfo pageInfo=new PageInfo(list);
        return new Response().setII(1,list!=null,pageInfo,"查询锁实时告警信息");
    }
}
src/main/java/com/whyc/service/LockHisService.java
@@ -18,7 +18,7 @@
    public Response getLockHis(int lockId, String startTime, String endTime, int pageNum, int pageSize) throws ParseException {
        LockHis his=new LockHis();
        his.setLockId(lockId);
        PageInfo pageInfo=util.getPageInfo(pageNum,pageSize, ThreadLocalUtil.parse(startTime,1),ThreadLocalUtil.parse(endTime,1)
        PageInfo pageInfo=util.getPageInfoWithOutDefault(pageNum,pageSize, ThreadLocalUtil.parse(startTime,1),ThreadLocalUtil.parse(endTime,1)
                ,"db_lock_his","tb_lock_his_"+lockId,his);
        return new Response().setII(1,pageInfo.getList()!=null,pageInfo,"查询锁的历史状态");
    }
src/main/java/com/whyc/service/SubTableService.java
@@ -1,6 +1,7 @@
package com.whyc.service;
import com.whyc.mapper.CallBack;
import com.whyc.pojo.db_lock_alarm.LockAlarmHis;
import com.whyc.pojo.db_lock_his.LockHis;
import com.whyc.util.ActionUtil;
import com.whyc.util.ThreadLocalUtil;
@@ -47,7 +48,7 @@
        return num;
    }
    //锁的历史记录
    public List<LockHis> getBattHisList(LockHis his) {
    public List<LockHis> getLockHisList(LockHis his) {
        String sql="SELECT * FROM db_lock_his."+ his.getRecordYear()+" history " +
                " where history.lock_id="+  his.getLockId() ;
        if(his.getStartTime()!=null){
@@ -78,4 +79,67 @@
    }
    //锁的告警历史记录总数
    public int getLockAlmHisCount(LockAlarmHis his) {
        String sql="SELECT  count(*) as number FROM db_lock_alarm."+ his.getRecordYear()+" history " +
                " where history.lock_id="+ his.getLockId() ;
        if(his.getStartTime()!=null){
            sql+=" and alm_start_time  >='"+ ThreadLocalUtil.format(his.getStartTime(),1)+"' ";
        }
        if(his.getEndTime()!=null){
            sql+=" and alm_start_time  <='"+ThreadLocalUtil.format(his.getEndTime(),1)+"' ";
        }
        List list = sqlExecuteService.executeQuery_call(sql, new CallBack() {
            @Override
            public List getResults(ResultSet rs) throws SQLException {
                LinkedList<Object> temp = new LinkedList<>();
                try {
                    while (rs.next())
                        temp.add(rs.getInt("number"));
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                return temp;
            }
        });
        int num =0;
        if(list!=null){
            num= (int) list.get(0);
        }
        return num;
    }
    //锁的告警历史记录
    public List<LockHis> getLockAlmHisList(LockAlarmHis his) {
        String sql="SELECT * FROM db_lock_alarm."+ his.getRecordYear()+" history " +
                " where history.lock_id="+  his.getLockId() ;
        if(his.getStartTime()!=null){
            sql+=" and alm_start_time  >='"+ ThreadLocalUtil.format(his.getStartTime(),1)+"' ";
        }
        if(his.getEndTime()!=null){
            sql+=" and alm_start_time  <='"+ThreadLocalUtil.format(his.getEndTime(),1)+"' ";
        }
        sql+="  ORDER BY alm_start_time asc  limit "+ his.getLimitStart()+","+ his.getLimitEnd()+" ";
        List<LockHis> list=sqlExecuteService.executeQuery_call(sql, new CallBack() {
            @Override
            public List getResults(ResultSet rs) throws SQLException {
                List list=new ArrayList();
                while (rs.next()){
                    LockAlarmHis data=new LockAlarmHis();
                    data.setNum(rs.getInt("num"));
                    data.setLockId(rs.getInt("lock_id"));
                    data.setAlmId(rs.getInt("alm_id"));
                    data.setAlmSource(rs.getInt("alm_source"));
                    data.setAlmStartTime(rs.getTimestamp("alm_start_time"));
                    data.setAlmConfirmedTime(rs.getTimestamp("alm_confirmed_time"));
                    data.setAlmEndTime(rs.getTimestamp("alm_end_time"));
                    data.setAlmIsConfirmed(rs.getInt("alm_is_confirmed"));
                    list.add(data);
                }
                return list;
            }
        });
        return list;
    }
}
src/main/java/com/whyc/util/SubTablePageInfoUtil.java
@@ -3,6 +3,7 @@
import com.github.pagehelper.PageInfo;
import com.whyc.factory.ThreadPoolExecutorFactory;
import com.whyc.mapper.CommonMapper;
import com.whyc.pojo.db_lock_alarm.LockAlarmHis;
import com.whyc.pojo.db_lock_his.LockHis;
import com.whyc.service.SubTableService;
import org.springframework.beans.BeanUtils;
@@ -27,9 +28,86 @@
    @Autowired
    private SubTableService service;
    //按年月分表
    /**按年份表分页查询*/
    public PageInfo<Object> getPageInfo(int pageNum,int pageSize,
                                                      Date startTime,Date endTime,
                                                      String dbName,String tablePrefix,
                                                      Object pojo) throws ParseException {
        Map<String, List<Date>> queryTimeForSubTables = DateUtil.getQueryTimeForSubTablesDesc2(startTime, endTime);
        //查询分表是否存在,存在则查询结果
        Map<String,Integer> queryCountMap = new LinkedHashMap<>();
        Set<String> tableYearKeySet = queryTimeForSubTables.keySet();
        for (String tableYear : tableYearKeySet) {
            List<Date> queryTime = queryTimeForSubTables.get(tableYear);
            //数值
            String tableName = tablePrefix+"_"+tableYear;
            String existTableName = commonMapper.existTable(dbName, tableName);
            if(existTableName == null){
                continue;
            }
            //====== 根据不同类型类型对象对应调整 ======
            if(pojo instanceof LockHis) {
                LockAlarmHis his = new LockAlarmHis();
                BeanUtils.copyProperties(pojo, his);
                his.setStartTime(queryTime.get(0));
                his.setEndTime(queryTime.get(1));
                his.setRecordYear(tableName);
                int currentCount = service.getLockAlmHisCount(his);
                queryCountMap.put(tableYear, currentCount);
            }
        }
        //分页信息
        //确认总页数,总记录数
        PageInfo<Object> pageInfo = new PageInfo<>();
        int total = 0;
        Set<String> queryKeySet = queryCountMap.keySet();
        for (String queryKey : queryKeySet) {
            int size = queryCountMap.get(queryKey);
            total+=size;
        }
        int pages = (int) Math.ceil(Float.parseFloat(String.valueOf(total))/pageSize);
        pageInfo.setTotal(total);
        pageInfo.setPages(pages);
        pageInfo.setPageNum(pageNum);
        pageInfo.setPageSize(pageSize);
        //根据当前页所需记录,查询当前页记录
        int startNum = (pageNum-1)*pageSize+1;
        int endNum = pageNum*pageSize;
        //最后一个算法:上面不应该先查询所有记录,应该取count. 这后面定位到哪个表或哪几张表后,采取limit获取当前页记录数;
        //格式:{表名,[limit 2,20]}
        Map<String,List<Integer>> tableAndLimitMap = MathUtil.getQueryTableAndLimit(startNum,endNum,pageSize,queryCountMap);
        Set<String> keySet = tableAndLimitMap.keySet();
        List<Object> dataList = new LinkedList<>();
        for (String key : keySet) {
            List<Date> queryTime = queryTimeForSubTables.get(key);
            //====== 根据不同类型类型对象对应调整 ======
            String recordYear = tablePrefix + "_" + key;
            if(pojo instanceof LockHis) {
                LockAlarmHis his = new LockAlarmHis();
                BeanUtils.copyProperties(pojo, his);
                his.setStartTime(queryTime.get(0));
                his.setEndTime(queryTime.get(1));
                his.setRecordYear(recordYear);
                List<Integer> limitList = tableAndLimitMap.get(key);
                his.setLimitStart(limitList.get(0));
                his.setLimitEnd(limitList.get(1));
                List<LockHis> list =  service.getLockAlmHisList(his);
                dataList.addAll(list);
            }
        }
        pageInfo.setList(dataList);
        return pageInfo;
    }
    /**按年份表分页查询*/
    public PageInfo<Object> getPageInfoWithOutDefault(int pageNum,int pageSize,
                                        Date startTime,Date endTime,
                                        String dbName,String tablePrefix,
                                        Object pojo) throws ParseException {
@@ -95,7 +173,7 @@
                List<Integer> limitList = tableAndLimitMap.get(key);
                his.setLimitStart(limitList.get(0));
                his.setLimitEnd(limitList.get(1));
                List<LockHis> list =  service.getBattHisList(his);
                List<LockHis> list =  service.getLockHisList(his);
                dataList.addAll(list);
            }
@@ -201,7 +279,7 @@
                List<Integer> limitList = tableAndLimitMap.get(key);
                his.setLimitStart(limitList.get(0));
                his.setLimitEnd(limitList.get(1));
                List<LockHis> list =  service.getBattHisList(his);
                List<LockHis> list =  service.getLockHisList(his);
                dataList.addAll(list);
            }
        }
src/main/java/com/whyc/webSocket/LockAlmRtSocket.java
New file
@@ -0,0 +1,98 @@
package com.whyc.webSocket;
import com.whyc.config.WebSocketConfig;
import com.whyc.dto.LockAlmDto;
import com.whyc.dto.Response;
import com.whyc.service.LockAlarmService;
import com.whyc.util.ActionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
@Component
@ServerEndpoint(value = "/lockAlmRt",encoders = WebSocketEncoder.class,configurator = WebSocketConfig.class)
public class LockAlmRtSocket {
    private Session session;
    private Thread thread;
    private static LockAlarmService almService;
    private volatile boolean runFlag = true;
    private volatile Map<String, Thread> threadMap = new HashMap<>();
    private volatile Map<Long,Boolean> threadFlagMap = new HashMap<>();
    @Autowired
    public void setLockAlarmService(LockAlarmService almService) {
        LockAlmRtSocket.almService = almService;
    }
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
    }
    @OnMessage
    public void onMessage(Session session, String message) {
        LockAlmDto almDto= ActionUtil.getGson().fromJson(message,LockAlmDto.class);
        thread = new Thread("Thread_areaLockStateSocket") {
            @Override
            public void run() {
                while (runFlag && !isInterrupted()) {
                    Thread thread = currentThread();
                    threadFlagMap.put(thread.getId(), true);
                    try {
                        Response res=almService.getLockAlm(almDto.getLockId(),almDto.getAlmId(),almDto.getPageNum(),almDto.getPageSize());
                        if (session.isOpen()) {
                            //推送信息
                            synchronized (session) {
                                session.getBasicRemote().sendObject(res);
                            }
                            threadFlagMap.put(thread.getId(), false);
                        }
                        sleep(4000);
                    } catch (Exception e) {
                        interrupt();
                    }
                }
            }
        };
        thread.start();
        threadFlagMap.put(thread.getId(),true);
        //停止老的socket线程
        Thread threadBefore = threadMap.get(session.getId());
        if(threadBefore !=null && threadBefore.isAlive()){
            while (threadFlagMap.get(threadBefore.getId())){
            }
            threadBefore.interrupt();
        }
        //将线程存储,便于调用定位
        threadMap.put(session.getId(), this.thread);
    }
    @OnClose
    public void onClose(CloseReason closeReason){
        System.err.println("closeReason = " + closeReason);
        runFlag = false;
        if (thread != null && thread.isAlive()) {
            thread.interrupt();
        }
        threadMap.remove(session.getId());
    }
    @OnError
    public void onError(Throwable error) {
        error.printStackTrace();
        if (thread != null && thread.isAlive()) {
            thread.interrupt();
        }
        threadMap.remove(session.getId());
    }
}