Pārlūkot izejas kodu

预警抓拍,预警升级代码合并

hanzhiwei 2 gadi atpakaļ
vecāks
revīzija
4c5a0d8e7c
70 mainītis faili ar 2924 papildinājumiem un 66 dzēšanām
  1. 23 0
      zd-api/zd-algorithm-api/src/main/java/com/zd/algorithm/api/alarm/domain/UserPhoneInfo.java
  2. 16 0
      zd-api/zd-algorithm-api/src/main/java/com/zd/algorithm/api/alarm/entity/AlarmEntrty.java
  3. 33 0
      zd-api/zd-algorithm-api/src/main/java/com/zd/algorithm/api/alarm/entity/AlarmLog.java
  4. 91 0
      zd-api/zd-laboratory-api/src/main/java/com/zd/laboratory/api/dto/WarningConfigDto.java
  5. 137 0
      zd-api/zd-laboratory-api/src/main/java/com/zd/laboratory/api/dto/WarningNoticeLogDto.java
  6. 13 0
      zd-api/zd-laboratory-api/src/main/java/com/zd/laboratory/api/feign/RemoteLabHardwareService.java
  7. 66 6
      zd-api/zd-laboratory-api/src/main/java/com/zd/laboratory/api/feign/RemoteLaboratoryService.java
  8. 5 0
      zd-api/zd-laboratory-api/src/main/java/com/zd/laboratory/api/feign/fallback/RemoteLabHardwareFallbackFactory.java
  9. 82 6
      zd-api/zd-laboratory-api/src/main/java/com/zd/laboratory/api/feign/fallback/RemoteLaboratoryFallbackFactory.java
  10. 5 0
      zd-model/src/main/java/com/zd/model/constant/BaseConstants.java
  11. 14 0
      zd-model/src/main/java/com/zd/model/entity/SysFile.java
  12. 78 0
      zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/config/ThreadPoolTaskConfig.java
  13. 4 0
      zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/domain/QpUseRecord.java
  14. 2 0
      zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/domain/vo/QpBottleStorageRVo.java
  15. 8 2
      zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/mapper/QpUseRecordMapper.java
  16. 6 0
      zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/service/IQpUseRecordService.java
  17. 247 10
      zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/service/impl/AlarmRecordServiceImpl.java
  18. 7 0
      zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/service/impl/QpUseRecordServiceImpl.java
  19. 6 0
      zd-modules/zd-airbottle/src/main/resources/mapper/airbottle/QpUseRecordMapper.xml
  20. 1 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/forward/serivce/ImageService.java
  21. 11 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/mqtt/MqttConfig.java
  22. 1 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/rfid/sdk/RfidClientImpl.java
  23. 7 0
      zd-modules/zd-base/src/main/java/com/zd/base/message/controller/WechatMsgController.java
  24. 5 0
      zd-modules/zd-base/src/main/java/com/zd/base/message/properties/WeChatProperties.java
  25. 7 0
      zd-modules/zd-base/src/main/java/com/zd/base/message/service/IWechatMsgSendService.java
  26. 29 0
      zd-modules/zd-base/src/main/java/com/zd/base/message/service/impl/WechatMsgSendServiceImpl.java
  27. 2 0
      zd-modules/zd-chemical/src/main/java/com/zd/chemical/ZdChemicalApplication.java
  28. 78 0
      zd-modules/zd-chemical/src/main/java/com/zd/chemical/config/ThreadPoolTaskConfig.java
  29. 370 20
      zd-modules/zd-chemical/src/main/java/com/zd/chemical/service/impl/HxpStockServiceImpl.java
  30. 43 4
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/controller/LabHardwareController.java
  31. 59 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/controller/WarningConfigController.java
  32. 19 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/controller/WarningDetailController.java
  33. 117 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/controller/WarningNoticeLogController.java
  34. 17 8
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/LabWarnPushMessage.java
  35. 107 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/WarningConfig.java
  36. 86 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/WarningDetail.java
  37. 149 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/WarningNoticeLog.java
  38. 14 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/dto/QueryAppWarningLogParam.java
  39. 29 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/dto/QueryWarningLogParam.java
  40. 15 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/vo/BottleVO.java
  41. 13 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/vo/ChemicalInfoVo.java
  42. 22 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/vo/MessageVO.java
  43. 117 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/vo/WarningNoticeLogVO.java
  44. 224 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/event/RedisExpiredPhotographListener.java
  45. 2 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/mapper/AlarmLogMapper.java
  46. 7 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/mapper/LabHardwareMapper.java
  47. 18 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/mapper/WarningConfigMapper.java
  48. 18 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/mapper/WarningDetailMapper.java
  49. 18 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/mapper/WarningNoticeLogMapper.java
  50. 7 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/IAlarmLogService.java
  51. 9 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/ILabHardwareService.java
  52. 16 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/WarningConfigService.java
  53. 16 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/WarningDetailService.java
  54. 31 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/WarningNoticeLogService.java
  55. 5 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/AlarmLogServiceImpl.java
  56. 5 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/LabHardwareServiceImpl.java
  57. 79 4
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/LabMessageContentServiceImpl.java
  58. 11 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/LabRiskPlanAbnormalDescServiceImpl.java
  59. 1 1
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/LabRiskPlanServiceImpl.java
  60. 1 1
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/LabWarnPushMessageServiceImpl.java
  61. 20 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/WarningConfigServiceImpl.java
  62. 20 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/WarningDetailServiceImpl.java
  63. 115 0
      zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/WarningNoticeLogServiceImpl.java
  64. 8 2
      zd-modules/zd-modules-laboratory/src/main/resources/bootstrap.yml
  65. 7 0
      zd-modules/zd-modules-laboratory/src/main/resources/mapper/laboratory/AlarmLogMapper.xml
  66. 9 0
      zd-modules/zd-modules-laboratory/src/main/resources/mapper/laboratory/LabHardwareMapper.xml
  67. 36 0
      zd-modules/zd-modules-laboratory/src/main/resources/mapper/laboratory/WarningConfigMapper.xml
  68. 29 0
      zd-modules/zd-modules-laboratory/src/main/resources/mapper/laboratory/WarningDetailMapper.xml
  69. 49 0
      zd-modules/zd-modules-laboratory/src/main/resources/mapper/laboratory/WarningNoticeLogMapper.xml
  70. 2 2
      zd-modules/zd-security/src/main/java/com/zd/security/CodeGenerator.java

+ 23 - 0
zd-api/zd-algorithm-api/src/main/java/com/zd/algorithm/api/alarm/domain/UserPhoneInfo.java

@@ -0,0 +1,23 @@
+package com.zd.algorithm.api.alarm.domain;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @Description 用户电话身份信息
+ * @Author hzw
+ * @Date 2023/6/20 20:29
+ * @Version 2.0
+ */
+@Data
+public class UserPhoneInfo {
+
+    @ApiModelProperty("用户昵称")
+    private String nickName;
+
+    @ApiModelProperty("手机号码")
+    private String phone;
+
+    @ApiModelProperty("角色")
+    private String role;
+}

+ 16 - 0
zd-api/zd-algorithm-api/src/main/java/com/zd/algorithm/api/alarm/entity/AlarmEntrty.java

@@ -1,8 +1,11 @@
 package com.zd.algorithm.api.alarm.entity;
 
 import cn.hutool.json.JSONUtil;
+import com.zd.algorithm.api.alarm.domain.UserPhoneInfo;
 import com.zd.model.constant.BaseConstants;
+
 import javax.validation.constraints.NotNull;
+import java.util.List;
 
 
 public class AlarmEntrty {
@@ -40,6 +43,11 @@ public class AlarmEntrty {
     @NotNull(message = "通知内容不能为空!")
     private String Text;
 
+    /**
+     * 本次打电话、发短信 电话用户信息
+     */
+    private List<UserPhoneInfo> userPhoneInfo;
+
     public AlarmEntrty() {
     }
 
@@ -108,6 +116,14 @@ public class AlarmEntrty {
         this.route = route;
     }
 
+    public List<UserPhoneInfo> getUserPhoneInfo() {
+        return userPhoneInfo;
+    }
+
+    public void setUserPhoneInfo(List<UserPhoneInfo> userPhoneInfo) {
+        this.userPhoneInfo = userPhoneInfo;
+    }
+
     @Override
     public String toString() {
         return JSONUtil.toJsonStr(this);

+ 33 - 0
zd-api/zd-algorithm-api/src/main/java/com/zd/algorithm/api/alarm/entity/AlarmLog.java

@@ -54,6 +54,15 @@ public class AlarmLog extends BaseEntity {
     @ApiModelProperty(value = "是否回写")
     private Integer isBack;
 
+    @ApiModelProperty(value = "用户昵称")
+    private String nickName;
+
+    @ApiModelProperty(value = "用户角色")
+    private String role;
+
+    @ApiModelProperty(value = "事件Id")
+    private Long keyId;
+
     private Date startTime;
 
     private Date endTime;
@@ -126,4 +135,28 @@ public class AlarmLog extends BaseEntity {
     public void setEndTime(Date endTime) {
         this.endTime = endTime;
     }
+
+    public String getNickName() {
+        return nickName;
+    }
+
+    public void setNickName(String nickName) {
+        this.nickName = nickName;
+    }
+
+    public String getRole() {
+        return role;
+    }
+
+    public void setRole(String role) {
+        this.role = role;
+    }
+
+    public Long getKeyId() {
+        return keyId;
+    }
+
+    public void setKeyId(Long keyId) {
+        this.keyId = keyId;
+    }
 }

+ 91 - 0
zd-api/zd-laboratory-api/src/main/java/com/zd/laboratory/api/dto/WarningConfigDto.java

@@ -0,0 +1,91 @@
+package com.zd.laboratory.api.dto;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @Description 告警配置传输类
+ * @Author hzw
+ * @Date 2023/6/15 10:23
+ * @Version 2.0
+ */
+@Data
+public class WarningConfigDto {
+    @ApiModelProperty("主键id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableId(value = "id", type = IdType.ASSIGN_ID)
+    private Long id;
+
+    @ApiModelProperty("预警类型(1算法识别 2化学品 3气瓶)")
+    private Integer warningType;
+
+    @ApiModelProperty("违规带离(1系统通知 2短信通知 3声光报警)")
+    private String illegalRemoval;
+
+    @ApiModelProperty("超时未归还(1系统通知 2短信通知 3声光报警)")
+    private String timeout;
+
+    @ApiModelProperty("已过期(1系统通知 2短信通知 3声光报警)")
+    private String expired;
+
+    @ApiModelProperty("即将过期(1系统通知 2短信通知 3声光报警)")
+    private String unexpired;
+
+    @ApiModelProperty("过期提醒数")
+    private Integer expiredWarnCount;
+
+    @ApiModelProperty("即将过期提醒天数")
+    private Integer unexpiredWarnDays;
+
+    @ApiModelProperty("穿戴检测周期")
+    private Integer wearDetectionCycle;
+
+    @ApiModelProperty("异常再识别率")
+    private Integer anomalyRate;
+
+    @ApiModelProperty("异常再识别数")
+    private Integer anomalyCount;
+
+    @ApiModelProperty("系统通知")
+    private Integer systemNotice;
+
+    @ApiModelProperty("短信通知")
+    private Integer messageNotice;
+
+    @ApiModelProperty("语音播报通知")
+    private Integer voiceNotcie;
+
+    @ApiModelProperty("创建人名称")
+    private String createName;
+
+    @ApiModelProperty("创建人ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long createBy;
+
+    @ApiModelProperty("创建时间")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("修改人名称")
+    private String updateName;
+
+    @ApiModelProperty("修改人ID")
+    @TableField(fill = FieldFill.UPDATE)
+    private Long updateBy;
+
+    @ApiModelProperty("修改时间")
+    @TableField(fill = FieldFill.UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty("是否删除(0否 1是)")
+    private Boolean isDeleted;
+
+}

+ 137 - 0
zd-api/zd-laboratory-api/src/main/java/com/zd/laboratory/api/dto/WarningNoticeLogDto.java

@@ -0,0 +1,137 @@
+package com.zd.laboratory.api.dto;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * @Description 预警内容传输类
+ * @Author hzw
+ * @Date 2023/6/14 18:26
+ * @Version 2.0
+ */
+@Data
+public class WarningNoticeLogDto {
+    @ApiModelProperty("主键id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableId(value = "id", type = IdType.ASSIGN_ID)
+    private Long id;
+
+    @ApiModelProperty("keyId")
+    private Long keyId;
+
+    @ApiModelProperty("预警内容")
+    private String warningContent;
+
+    @ApiModelProperty("预警类型(1算法识别 2化学品 3气瓶 4预案")
+    private Integer warningType;
+
+    @ApiModelProperty("预警下级类型(1违规带离,2超时未归还,3即将过期 4已过期)")
+    private Integer warningSubType;
+
+    @ApiModelProperty("预警方式(1系统通知 2短信通知 3声光报警)")
+    private String warningWay;
+
+    @ApiModelProperty("实验室id")
+    private Long subId;
+
+    @ApiModelProperty("实验室名称")
+    private String subName;
+
+    @ApiModelProperty("楼栋名称")
+    private String buildName;
+
+    @ApiModelProperty("楼层名称")
+    private String floorName;
+
+    @ApiModelProperty("房间号")
+    private String roomNum;
+
+    @ApiModelProperty("预警时间")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime warningTime;
+
+    @ApiModelProperty("气体/化学品名称")
+    private String name;
+
+    @ApiModelProperty("余量")
+    private BigDecimal margin;
+
+    @ApiModelProperty("规格")
+    private String specification;
+
+    @ApiModelProperty("申领人")
+    private String apply;
+
+    @ApiModelProperty("申领时间")
+    private LocalDateTime applyTime;
+
+    @ApiModelProperty("存放位置")
+    private String deposit;
+
+    @ApiModelProperty("记录视频")
+    private String recordVideo;
+
+    @ApiModelProperty("记录照片")
+    private String recordPhoto;
+
+    @ApiModelProperty("持续时间")
+    private Integer riskDuration;
+
+    @ApiModelProperty("响应人员")
+    private String responder;
+
+    @ApiModelProperty("室内人员")
+    private String indoorUser;
+    @ApiModelProperty("预案开始时间")
+    private LocalDateTime startTime;
+
+    @ApiModelProperty("预案结束时间")
+    private LocalDateTime endTime;
+
+    @ApiModelProperty("入库时间")
+    private LocalDateTime entryTime;
+
+    @ApiModelProperty("过期时间")
+    private LocalDateTime expirationTime;
+
+    @ApiModelProperty("所有人")
+    private String holder;
+
+    @ApiModelProperty("是否语音播报(0否 1是)")
+    private Integer voiceBroadcast;
+
+    @ApiModelProperty("创建人名称")
+    private String createName;
+
+    @ApiModelProperty("创建人ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long createBy;
+
+    @ApiModelProperty("创建时间")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("修改人名称")
+    private String updateName;
+
+    @ApiModelProperty("修改人ID")
+    @TableField(fill = FieldFill.UPDATE)
+    private Long updateBy;
+
+    @ApiModelProperty("修改时间")
+    @TableField(fill = FieldFill.UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty("是否删除(0否 1是)")
+    private Boolean isDeleted;
+}

+ 13 - 0
zd-api/zd-laboratory-api/src/main/java/com/zd/laboratory/api/feign/RemoteLabHardwareService.java

@@ -24,4 +24,17 @@ public interface RemoteLabHardwareService {
     @ApiOperation(value = "离线设备列表")
     @GetMapping("/remote/hardware/list")
     ResultData list(@RequestParam("type") String type, @RequestParam("operate") String operate);
+
+    /**
+     * 根据类型查询摄像头信息
+     * @Param [subId 实验室id,
+     *          type 设备类型(0,一体机 1,电源开关 2 智能通风,3,语音对讲,4,视频监控5,智能终端 6,智能门锁 ,7,RFID识别器,8,智能报警器,9,智能柜锁,11 海康门禁),
+     *          pcType 摄像头类型:(0火焰算法 1穿戴识别 2违规带离抓拍)]
+     * @Return com.zd.laboratory.domain.LabHardware
+     **/
+    @ApiOperation(value = "根据类型查询摄像头信息")
+    @GetMapping("/hardware/findCameraByType")
+    ResultData findCameraByType(@RequestParam("subId") Long subId,
+                                @RequestParam("type") Integer type,
+                                @RequestParam("pcType") Integer pcType);
 }

+ 66 - 6
zd-api/zd-laboratory-api/src/main/java/com/zd/laboratory/api/feign/RemoteLaboratoryService.java

@@ -1,17 +1,20 @@
 package com.zd.laboratory.api.feign;
 
+import com.zd.laboratory.api.dto.CheckSubjectDto;
+import com.zd.laboratory.api.dto.WarningConfigDto;
+import com.zd.laboratory.api.dto.WarningNoticeLogDto;
 import com.zd.laboratory.api.entity.LabGradeManageRecord;
 import com.zd.laboratory.api.entity.LabMessageContent;
 import com.zd.laboratory.api.entity.LabSubjectEntityVO;
 import com.zd.laboratory.api.entity.OneClickFireDTO;
-import com.zd.model.domain.ResultData;
-import com.zd.model.entity.RemoteLabHardware;
 import com.zd.laboratory.api.feign.fallback.RemoteLaboratoryFallbackFactory;
 import com.zd.laboratory.api.vo.LabGradeManageWorkVO;
 import com.zd.model.constant.ApplicationConstants;
 import com.zd.model.domain.AjaxResult;
 import com.zd.model.domain.R;
+import com.zd.model.domain.ResultData;
 import com.zd.model.entity.Algorithm;
+import com.zd.model.entity.RemoteLabHardware;
 import com.zd.model.entity.TotalByID;
 import com.zd.model.enums.HardwareOperate;
 import com.zd.model.page.TableDataInfo;
@@ -496,10 +499,6 @@ public interface RemoteLaboratoryService {
     @PostMapping("/plan/oneClickFire")
     ResultData oneClickFire(@RequestBody OneClickFireDTO oneClickFireDTO);
 
-    @ApiOperation(value = "根据实验室id查询实验室位置信息")
-    @PostMapping("/buildFloorLayout/getPositionBySubId")
-    ResultData getPositionBySubId(@RequestParam("subIds") String subIds);
-
     @ApiOperation(value = "根据用户id查询用户关联的白名单实验室")
     @GetMapping("/whitelist/subWhiteList")
     ResultData getWhiteSubList(@RequestParam("userId") Long userId);
@@ -507,4 +506,65 @@ public interface RemoteLaboratoryService {
     @ApiOperation(value = "根据用户id查询用户关联的未过期的安全准入实验室")
     @GetMapping("/apply/getApplySubList")
     ResultData getApplySubList(@RequestParam("userId") Long userId);
+
+    @ApiOperation(value = "根据实验室ids查询实验室信息")
+    @GetMapping("/subject/findSubjectInfoList")
+    ResultData<List<CheckSubjectDto>> findSubjectInfoList(@RequestParam("subIds") String subIds);
+
+    @ApiOperation(value = "根据实验室id查询RFID实验室详情")
+    @GetMapping("/subject/getPositionBySubId")
+    ResultData getPositionBySubId(@RequestParam("subIds") String subIds);
+
+
+    @ApiOperation(value = "查询安全准入审批记录列表")
+    @GetMapping("/apply/getStuList")
+    public TableDataInfo getStuList(@RequestBody Map applyMap);
+
+    @ApiOperation(value = "根据实验室ids查询实验室信息")
+    @GetMapping("/subject/selectLabSubSafeInfoByIds")
+    ResultData selectLabSubSafeInfoByIds(@RequestParam("ids") Long[] ids);
+
+    @ApiOperation(value = "查询全校实验室dis")
+    @GetMapping("/subject/getAllSubIds")
+    ResultData getAllSubIds();
+
+    @ApiOperation(value = "查询学院实验室dis")
+    @GetMapping("/subject/getCollegeSubIds")
+    ResultData getCollegeSubIds(@RequestParam(value = "deptIds") Long[] deptIds);
+
+    @ApiOperation(value = "根据实验室id查询实验室危险源信息")
+    @GetMapping("/hardware/getBySubjectId")
+    R getBySubjectId(@RequestParam("subjectId") Long subjectId);
+
+    @ApiOperation(value = "查询安全分级")
+    @GetMapping("/classified/listAll")
+    R classifiedListAll();
+
+    @ApiOperation(value = "查询安全分类")
+    @GetMapping("/classtype/listAll")
+    R classtypeListAll();
+
+    @ApiOperation(value = "查询安全分级")
+    @GetMapping("/hardware/getBySubjectIds")
+    R getBySubjectIds(@RequestParam("ids") Long... ids);
+
+    @ApiOperation(value = "根据实验室ids查询实验室信息")
+    @GetMapping("/checkRecord/signatureByUserId/{userId}")
+    ResultData signatureByUserId(@PathVariable("userId") Long userId);
+
+    @ApiOperation("新增报警记录日志")
+    @PostMapping("/warningNoticeLog/add")
+    ResultData addWarningNoticeLog(@RequestBody WarningNoticeLogDto warningNoticeLogDto);
+
+    @ApiOperation("修改报警记录日志")
+    @PostMapping("/warningNoticeLog/update")
+    ResultData updateWarningNoticeLog(@RequestBody WarningNoticeLogDto warningNoticeLogDto);
+
+    @ApiOperation("根据keyId获取过期提醒次数")
+    @GetMapping("/warningNoticeLog/getRemindData")
+    ResultData getRemindData(@RequestParam("keyId") Long keyId);
+
+    @GetMapping("/warningConfig/getByType")
+    @ApiOperation("根据类型查询报警配置信息-预警类型(1算法识别 2化学品 3气瓶)")
+    ResultData<WarningConfigDto> getByType(@RequestParam("type") Integer type);
 }

+ 5 - 0
zd-api/zd-laboratory-api/src/main/java/com/zd/laboratory/api/feign/fallback/RemoteLabHardwareFallbackFactory.java

@@ -28,6 +28,11 @@ public class RemoteLabHardwareFallbackFactory implements FallbackFactory<RemoteL
             public ResultData list(String type, String operate) {
                 return ResultData.fail("请求失败!");
             }
+
+            @Override
+            public ResultData findCameraByType(Long subId, Integer type, Integer pcType) {
+                return ResultData.fail("请求失败!");
+            }
         };
     }
 }

+ 82 - 6
zd-api/zd-laboratory-api/src/main/java/com/zd/laboratory/api/feign/fallback/RemoteLaboratoryFallbackFactory.java

@@ -1,16 +1,19 @@
 package com.zd.laboratory.api.feign.fallback;
 
+import com.zd.laboratory.api.dto.CheckSubjectDto;
+import com.zd.laboratory.api.dto.WarningConfigDto;
+import com.zd.laboratory.api.dto.WarningNoticeLogDto;
 import com.zd.laboratory.api.entity.LabGradeManageRecord;
 import com.zd.laboratory.api.entity.LabMessageContent;
 import com.zd.laboratory.api.entity.LabSubjectEntityVO;
 import com.zd.laboratory.api.entity.OneClickFireDTO;
-import com.zd.model.domain.ResultData;
-import com.zd.model.entity.RemoteLabHardware;
 import com.zd.laboratory.api.feign.RemoteLaboratoryService;
 import com.zd.laboratory.api.vo.LabGradeManageWorkVO;
 import com.zd.model.domain.AjaxResult;
 import com.zd.model.domain.R;
+import com.zd.model.domain.ResultData;
 import com.zd.model.entity.Algorithm;
+import com.zd.model.entity.RemoteLabHardware;
 import com.zd.model.entity.TotalByID;
 import com.zd.model.enums.HardwareOperate;
 import com.zd.model.page.TableDataInfo;
@@ -457,18 +460,91 @@ public class RemoteLaboratoryFallbackFactory implements FallbackFactory<RemoteLa
             }
 
             @Override
+            public ResultData getWhiteSubList(Long userId) {
+                return ResultData.fail("根据用户id查询用户关联的白名单实验室失败!"+ cause.getMessage());
+            }
+
+            @Override
+            public ResultData getApplySubList(Long userId) {
+                return ResultData.fail("根据用户id查询用户关联的安全准入实验室失败!"+ cause.getMessage());
+            }
+
+            @Override
+            public ResultData<List<CheckSubjectDto>> findSubjectInfoList(String subIds) {
+                return ResultData.fail("查询实验室位置信息失败!"+ cause.getMessage());
+            }
+
+            @Override
             public ResultData getPositionBySubId(String subIds) {
                 return ResultData.fail("查询实验室位置信息失败!"+ cause.getMessage());
             }
 
             @Override
-            public ResultData getWhiteSubList(Long userId) {
-                return ResultData.fail("根据用户id查询用户关联的白名单实验室失败!"+ cause.getMessage());
+            public TableDataInfo getStuList(Map applyMap) {
+                TableDataInfo tableDataInfo = new TableDataInfo();
+                tableDataInfo.setMsg("查询学员准入列表失败:" + cause.getMessage());
+                tableDataInfo.setCode(500);
+                return tableDataInfo;
             }
 
             @Override
-            public ResultData getApplySubList(Long userId) {
-                return ResultData.fail("根据用户id查询用户关联的安全准入实验室失败!"+ cause.getMessage());
+            public ResultData selectLabSubSafeInfoByIds(Long... ids) {
+                return ResultData.fail("查询实验室信息失败!"+ cause.getMessage());
+            }
+
+            @Override
+            public ResultData getAllSubIds() {
+                return ResultData.fail("查询实验室信息失败!"+ cause.getMessage());
+            }
+
+            @Override
+            public ResultData getCollegeSubIds(Long[] deptIds) {
+                return ResultData.fail("查询实验室信息失败!"+ cause.getMessage());
+            }
+
+            @Override
+            public R getBySubjectId(Long subjectId) {
+                return R.fail("查询实验室危险源信息失败!"+ cause.getMessage());
+            }
+
+            @Override
+            public R classifiedListAll() {
+                return R.fail("查询实验室安全分级信息失败!"+ cause.getMessage());
+            }
+
+            @Override
+            public R classtypeListAll() {
+                return R.fail("查询实验室安全分级信息失败!"+ cause.getMessage());
+            }
+
+            @Override
+            public R getBySubjectIds(Long... ids) {
+                return R.fail("根据实验室ids集合查询危险源数量信息失败!"+ cause.getMessage());
+            }
+
+            @Override
+            public ResultData signatureByUserId(Long userId) {
+                return ResultData.fail("获取用户签章信息!"+ cause.getMessage());
+            }
+
+            @Override
+            public ResultData addWarningNoticeLog(WarningNoticeLogDto warningNoticeLogDto) {
+                return ResultData.fail("新增告警通知日志!"+ cause.getMessage());
+            }
+
+            @Override
+            public ResultData updateWarningNoticeLog(WarningNoticeLogDto warningNoticeLogDto) {
+                return ResultData.fail("修改告警通知日志!"+ cause.getMessage());
+            }
+
+            @Override
+            public ResultData getRemindData(Long keyId) {
+                return ResultData.fail("获取告警次数失败!"+ cause.getMessage());
+            }
+
+            @Override
+            public ResultData<WarningConfigDto> getByType(Integer type) {
+                return ResultData.fail("获取告警通知配置失败!"+ cause.getMessage());
             }
         };
     }

+ 5 - 0
zd-model/src/main/java/com/zd/model/constant/BaseConstants.java

@@ -193,4 +193,9 @@ public interface BaseConstants {
      * Redis前缀,需统一
      */
     String REDIS_LOCK = "redis_lock:";
+
+    /**
+     * 抓拍队列
+     */
+    String PHOTOGRAPH_QUEUE = "photographQueue";
 }

+ 14 - 0
zd-model/src/main/java/com/zd/model/entity/SysFile.java

@@ -2,6 +2,7 @@ package com.zd.model.entity;
 
 import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * 文件信息
@@ -19,6 +20,11 @@ public class SysFile {
      */
     private String url;
 
+    /**
+     * 文件
+     */
+    private MultipartFile multipartFile;
+
     public String getName() {
         return name;
     }
@@ -35,6 +41,14 @@ public class SysFile {
         this.url = url;
     }
 
+    public MultipartFile getMultipartFile() {
+        return multipartFile;
+    }
+
+    public void setMultipartFile(MultipartFile multipartFile) {
+        this.multipartFile = multipartFile;
+    }
+
     @Override
     public String toString() {
         return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)

+ 78 - 0
zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/config/ThreadPoolTaskConfig.java

@@ -0,0 +1,78 @@
+package com.zd.airbottle.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.concurrent.BasicThreadFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.*;
+
+/**
+ * @author Administrator
+ */
+@Configuration
+@Slf4j
+public class ThreadPoolTaskConfig {
+
+    private static final int CORE_POOL_SIZE = 10;
+    private static final int MAX_POOL_SIZE = 100;
+    private static final int KEEP_ALIVE_TIME = 10;
+    private static final int QUEUE_CAPACITY = 200;
+    private static final String THREAD_NAME_PREFIX = "Async-Service-";
+
+    @Bean("taskExecutor")
+    public ThreadPoolTaskExecutor threadPoolTaskExecutor(){
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(CORE_POOL_SIZE);
+        executor.setMaxPoolSize(MAX_POOL_SIZE);
+        executor.setQueueCapacity(QUEUE_CAPACITY);
+        executor.setKeepAliveSeconds(KEEP_ALIVE_TIME);
+        executor.setThreadNamePrefix(THREAD_NAME_PREFIX);
+
+        // 线程池对拒绝任务的处理策略
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        // 初始化
+        executor.initialize();
+        return executor;
+    }
+
+    /**
+     * 执行定时任务
+     */
+    @Bean(name = "scheduledExecutorService")
+    public ScheduledExecutorService scheduledExecutorService() {
+        return new ScheduledThreadPoolExecutor(CORE_POOL_SIZE,
+                new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build()) {
+            @Override
+            protected void afterExecute(Runnable r, Throwable t) {
+                super.afterExecute(r, t);
+                printException(r, t);
+            }
+        };
+    }
+
+
+    /**
+     * 打印线程异常信息
+     */
+    public static void printException(Runnable r, Throwable t) {
+        if (t == null && r instanceof Future<?>) {
+            try {
+                Future<?> future = (Future<?>) r;
+                if (future.isDone()) {
+                    future.get();
+                }
+            } catch (CancellationException ce) {
+                t = ce;
+            } catch (ExecutionException ee) {
+                t = ee.getCause();
+            } catch (InterruptedException ie) {
+                Thread.currentThread().interrupt();
+            }
+        }
+        if (t != null) {
+            log.error(t.getMessage(), t);
+        }
+    }
+}

+ 4 - 0
zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/domain/QpUseRecord.java

@@ -70,6 +70,10 @@ public class QpUseRecord extends BaseEntity
     @Excel(name = "使用量")
     @ApiModelProperty(value = "使用量")
     private BigDecimal amount;
+    /** 使用状态 使用状态(1.使用中,2已归还,3超时未归还) */
+    @Excel(name = "使用状态")
+    @ApiModelProperty(value = "使用状态")
+    private Integer userStatus;
     /** 使用时间 */
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @Excel(name = "使用时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")

+ 2 - 0
zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/domain/vo/QpBottleStorageRVo.java

@@ -221,4 +221,6 @@ public class QpBottleStorageRVo {
     @ApiModelProperty(value = "联系方式")
     private String ownerPhone;
 
+    @ApiModelProperty(value = "入库时间")
+    private Date createTime;
 }

+ 8 - 2
zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/mapper/QpUseRecordMapper.java

@@ -1,13 +1,13 @@
 package com.zd.airbottle.mapper;
 
-import java.util.List;
-
 import com.zd.airbottle.domain.QpUseRecord;
 import com.zd.airbottle.domain.vo.QpAirGoodsConfigRelationVo;
 import com.zd.airbottle.domain.vo.QpUseRecordVo;
 import com.zd.airbottle.domain.vo.report.AirAmount;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 /**
  * 使用记录Mapper接口
  */
@@ -131,4 +131,10 @@ public interface QpUseRecordMapper {
      * @return
      */
     QpUseRecord selectQpUseRecordByIdstorageId(Long storageId);
+
+    /**
+     * 查询未归还的记录
+     * @return
+     */
+    List<QpUseRecord> selectNoReturnRecords();
 }

+ 6 - 0
zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/service/IQpUseRecordService.java

@@ -140,4 +140,10 @@ public interface IQpUseRecordService
      * @return
      */
     QpUseRecord selectQpUseRecordByIdstorageId(Long storageId);
+
+    /**
+     * 查询未归还记录
+     * @return
+     */
+    List<QpUseRecord> selectNoReturnRecords();
 }

+ 247 - 10
zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/service/impl/AlarmRecordServiceImpl.java

@@ -1,28 +1,37 @@
 package com.zd.airbottle.service.impl;
 
+import cn.hutool.core.date.LocalDateTimeUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
 import com.zd.airbottle.domain.AlarmRecord;
+import com.zd.airbottle.domain.QpAirBottle;
 import com.zd.airbottle.domain.QpUseRecord;
-import com.zd.airbottle.domain.vo.AlarmRecordVo;
-import com.zd.airbottle.domain.vo.BottleStorageInfoVo;
-import com.zd.airbottle.domain.vo.QpBottleStorageRVo;
+import com.zd.airbottle.domain.vo.*;
 import com.zd.airbottle.mapper.AlarmRecordMapper;
-import com.zd.airbottle.service.IAlarmRecordService;
-import com.zd.airbottle.service.IQpBottleStorageService;
-import com.zd.airbottle.service.IQpUseRecordService;
+import com.zd.airbottle.service.*;
 import com.zd.algorithm.api.alarm.entity.AlarmEntrty;
 import com.zd.algorithm.api.alarm.entity.Routes;
 import com.zd.algorithm.api.alarm.entity.SendTypes;
 import com.zd.algorithm.api.alarm.feign.RemoteAlarmService;
+import com.zd.algorithm.api.camera.feign.RemoteCameraService;
 import com.zd.algorithm.api.rfid.feign.RemoteRfidService;
 import com.zd.base.api.feign.RemoteMessageService;
 import com.zd.common.core.redis.RedisService;
+import com.zd.common.core.utils.SpringUtils;
 import com.zd.common.core.utils.StringUtils;
+import com.zd.laboratory.api.dto.CheckSubjectDto;
+import com.zd.laboratory.api.dto.WarningConfigDto;
+import com.zd.laboratory.api.dto.WarningNoticeLogDto;
+import com.zd.laboratory.api.entity.LabMessageContent;
 import com.zd.laboratory.api.entity.LabSubjectEntity;
+import com.zd.laboratory.api.feign.RemoteLabHardwareService;
 import com.zd.laboratory.api.feign.RemoteLaboratoryService;
+import com.zd.laboratory.api.feign.RemoteMessageContentService;
 import com.zd.laboratory.api.feign.RemoteSubQueryService;
 import com.zd.model.constant.HttpStatus;
 import com.zd.model.domain.AjaxResult;
 import com.zd.model.domain.R;
+import com.zd.model.domain.ResultData;
 import com.zd.model.entity.HardwareRfidDto;
 import com.zd.model.entity.InventoryTag;
 import com.zd.model.entity.RemoteLabHardware;
@@ -30,15 +39,20 @@ import com.zd.model.entity.TemplateResult;
 import com.zd.system.api.feign.RemoteUserService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.concurrent.BasicThreadFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
 import java.util.*;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * 报警记录Service业务层处理
@@ -66,6 +80,22 @@ public class AlarmRecordServiceImpl implements IAlarmRecordService {
     private RemoteMessageService messageService;
     @Resource
     private RemoteRfidService remoteRfidService;
+    @Resource
+    private RemoteLabHardwareService remoteLabHardwareService;
+    private static final ScheduledExecutorService scheduledExecutorService = SpringUtils.getBean("scheduledExecutorService");
+    @Autowired
+    private RemoteCameraService remoteCameraService;
+    @Autowired
+    private RemoteMessageContentService remoteMessageContentService;
+
+    @Autowired
+    private IQpAirBottleService qpAirBottleService;
+
+    @Autowired
+    private IQpUsegasApplyService qpUsegasApplyService;
+
+    @Autowired
+    private IQpQualificationApplyService qualificationApplyService;
 
     private static final String RFID_CODE = "RFID:";
 
@@ -102,10 +132,96 @@ public class AlarmRecordServiceImpl implements IAlarmRecordService {
         String electronicTag = alarmRecord.getElectronicTag();
         QpBottleStorageRVo storageRVo = storageService.getByElectronicTag(electronicTag);
         if (storageRVo != null) {
-            if (hardwareRfidDto!=null && storageRVo.getStorageStatus() == 1){
-                //RFID设备报警
-                R<Boolean> alarm = remoteRfidService.alarm(hardwareRfidDto);
-                log.info("==================>{},{}",alarm.getCode(),alarm.getMsg());
+            if (storageRVo.getStorageStatus() == 1){
+                // 查询配置
+                ResultData<WarningConfigDto> byType = laboratoryService.getByType(3);
+                if (HttpStatus.SUCCESS != byType.getCode()) {
+                    return 0;
+                }
+                //违规带离(1系统通知 2短信通知 3声光报警)
+                WarningConfigDto warningConfigDto = byType.getData();
+                String illegalRemoval = warningConfigDto.getIllegalRemoval();
+
+                WarningNoticeLogDto warningNoticeLogDto = new WarningNoticeLogDto();
+                warningNoticeLogDto.setKeyId(storageRVo.getId());
+                warningNoticeLogDto.setName(storageRVo.getAirName());
+                warningNoticeLogDto.setWarningType(3);
+                warningNoticeLogDto.setWarningSubType(1);
+                warningNoticeLogDto.setWarningContent("气瓶违规带离");
+                warningNoticeLogDto.setWarningTime(LocalDateTime.now());
+                warningNoticeLogDto.setWarningWay(illegalRemoval);
+                warningNoticeLogDto.setHolder(storageRVo.getOwner());
+                warningNoticeLogDto.setDeposit(storageRVo.getLocation());
+                warningNoticeLogDto.setMargin(new BigDecimal(storageRVo.getCurrentPressure()));
+                warningNoticeLogDto.setSpecification(storageRVo.getConfigName());
+                warningNoticeLogDto.setEntryTime(LocalDateTimeUtil.of(storageRVo.getCreateTime()));
+
+                //查询到实验室负责人id 安全责任人id
+                ResultData<List<CheckSubjectDto>> subjectInfoList = laboratoryService.findSubjectInfoList(String.valueOf(storageRVo.getSubjectId()));
+                StringBuffer userIds = new StringBuffer();
+                StringBuffer phones = new StringBuffer();
+                if (HttpStatus.SUCCESS == subjectInfoList.getCode()) {
+                    List<CheckSubjectDto> data = subjectInfoList.getData();
+                    CheckSubjectDto i = data.get(0);
+                    warningNoticeLogDto.setSubId(i.getSubId());
+                    warningNoticeLogDto.setSubName(i.getSubjectName());
+                    warningNoticeLogDto.setBuildName(i.getBuildName());
+                    warningNoticeLogDto.setFloorName(i.getFloorName());
+                    warningNoticeLogDto.setRoomNum(i.getRoomNumber());
+                    userIds.append(i.getSafeUserId()).append(",").append(i.getAdminId());
+                    phones.append(i.getAdminPhone()).append(",").append(i.getSafeUserPhone());
+                }
+                ResultData resultData = laboratoryService.addWarningNoticeLog(warningNoticeLogDto);
+                if (HttpStatus.SUCCESS != resultData.getCode()) {
+                    return 0;
+                }
+                Long logId = (Long)resultData.getData();
+                if(illegalRemoval != null){
+                    String text = "【实验室安全系统】实验室名称-实验人员违规X气携带气瓶离开房间,发生时间:"+ LocalDateTimeUtil.format(LocalDateTime.now(),"yyyy-MM-dd HH:mm:ss") +",请尽快确认。点击查看:"+"http://";
+                    if (illegalRemoval.contains("1")) {
+                        //系统通知
+                        LabMessageContent labMessageContent = new LabMessageContent();
+                        labMessageContent.setSendMode(2);
+                        labMessageContent.setSendRange(3);
+                        labMessageContent.setMessClass(1);
+                        labMessageContent.setMessType(13);
+                        labMessageContent.setSubIds(String.valueOf(storageRVo.getSubjectId()));
+                        labMessageContent.setUserIds(userIds.toString());
+                        labMessageContent.setContent(text);
+                        remoteMessageContentService.sendMessage(labMessageContent);
+
+                    }
+                    if (illegalRemoval.contains("2")) {
+                        //短信通知
+                        String[] strings = Stream.of(phones.toString().split(","))
+                                .filter(a -> StrUtil.isNotBlank(a))
+                                .collect(Collectors.joining(","))
+                                .split(",");
+
+                        if (strings != null) {
+                            AlarmEntrty alarmEntrty = new AlarmEntrty(Routes.NoticePush, strings,SendTypes.SMS.toString(),text);
+                            remoteAlarmService.send(alarmEntrty);
+                            log.info("气瓶发送短信打电话消息推送完成!");
+                        }
+                    }
+                    if (hardwareRfidDto != null && illegalRemoval.contains("3")) {
+                        //声光报警
+                        R<Boolean> alarm = remoteRfidService.alarm(hardwareRfidDto);
+                        log.info("==================>{},{}",alarm.getCode(),alarm.getMsg());
+                    }
+                    // TODO 报警的同时传入摄像头ip
+                    ResultData result = remoteLabHardwareService.findCameraByType(storageRVo.getSubjectId(), 4, 2);
+                    if (HttpStatus.SUCCESS == result.getCode()) {
+                        String ip = String.valueOf(result.getData());
+                        startVideo(ip);
+                        scheduledExecutorService.schedule(new TimerTask() {
+                            @Override
+                            public void run() {
+                                stopVideo(ip,logId);
+                            }
+                        }, 30, TimeUnit.SECONDS);
+                    }
+                }
             }else {
                 return 0;
             }
@@ -131,6 +247,35 @@ public class AlarmRecordServiceImpl implements IAlarmRecordService {
         return 0;
     }
 
+    private void startVideo(String cameraIpAddress) {
+        if(org.apache.commons.lang3.StringUtils.isNotBlank(cameraIpAddress)){
+            R r = remoteCameraService.startRecord(cameraIpAddress);
+            log.info("报警模块-开始录制视频返回结果打印={}", JSON.toJSONString(r));
+            if (r.getCode() == HttpStatus.SUCCESS) {
+                log.info("报警模块-开始录制视频成功!");
+            } else {
+                log.info("报警模块-开始录制视频失败!");
+            }
+        }else {
+            log.info("报警模块-摄像头ip为空!");
+        }
+    }
+    private void stopVideo(String cameraIpAddress,Long logId) {
+        if(org.apache.commons.lang3.StringUtils.isNotBlank(cameraIpAddress)){
+            R r = remoteCameraService.stopRecord(cameraIpAddress);
+            log.info("报警模块-录制视频结束返回结果打印={}", JSON.toJSONString(r));
+            if (r.getCode() == HttpStatus.SUCCESS) {
+                String recordVideo = String.valueOf(r.getData());
+                WarningNoticeLogDto warningNoticeLogDto = new WarningNoticeLogDto();
+                warningNoticeLogDto.setId(logId);
+                warningNoticeLogDto.setRecordVideo(recordVideo);
+                laboratoryService.updateWarningNoticeLog(warningNoticeLogDto);
+            } else {
+                log.info("报警模块-结束录制视频失败!");
+            }
+        }
+    }
+
     private void sendAlarm(QpBottleStorageRVo storageRVo) {
         Long subjectId = storageRVo.getSubjectId();
         R<List<LabSubjectEntity>> resultList = remoteSubQueryService.listByIds(Collections.singletonList(subjectId));
@@ -260,4 +405,96 @@ public class AlarmRecordServiceImpl implements IAlarmRecordService {
         }
         return Collections.emptyList();
     }
+
+    /**
+     * 气瓶超时定时任务
+     * @Param []
+     * @Return void
+     **/
+//    @Scheduled(cron = "0 0/1 * * * ? ")
+    @Scheduled(cron = "0 0 0 * * ?")
+    public void hxpTimeOut() {
+        // 查询配置
+        ResultData<WarningConfigDto> byType = laboratoryService.getByType(3);
+        if (HttpStatus.SUCCESS != byType.getCode()) {
+            log.info("未查询到相关配置!");
+            return;
+        }
+        WarningConfigDto warningConfigDto = byType.getData();
+        //气瓶超时未归还
+        List<QpUseRecord> qpUseRecords = useRecordService.selectNoReturnRecords();
+        Optional.ofNullable(qpUseRecords).orElseGet(Collections::emptyList).forEach(QpUseRecord -> {
+
+            QpBottleStorageVO qpBottleStorageVO = storageService.selectQpBottleStorageById(QpUseRecord.getStorageId());
+            QpAirBottle qpAirBottle = qpAirBottleService.selectQpAirBottleById(qpBottleStorageVO.getAirBottleId());
+
+            //过期时间在提醒天数内 并且在一天之内
+            WarningNoticeLogDto warningNoticeLogDto = new WarningNoticeLogDto();
+            warningNoticeLogDto.setKeyId(qpBottleStorageVO.getId());
+            warningNoticeLogDto.setName(qpAirBottle.getAirName());
+            warningNoticeLogDto.setWarningType(3);
+            warningNoticeLogDto.setWarningSubType(2);
+            warningNoticeLogDto.setWarningContent("气瓶超时未归还");
+
+            warningNoticeLogDto.setWarningTime(LocalDateTime.now());
+            //TODO 余量
+            warningNoticeLogDto.setMargin(BigDecimal.ZERO);
+//            warningNoticeLogDto.setSpecification(String.valueOf(hxpStock.getChemicalAmount()));
+
+            //查询到实验室负责人id 安全责任人id
+            ResultData<List<CheckSubjectDto>> subjectInfoList = laboratoryService.findSubjectInfoList(String.valueOf(qpBottleStorageVO.getSubjectId()));
+            StringBuffer userIdStr = new StringBuffer();
+            StringBuffer phones = new StringBuffer();
+            if (HttpStatus.SUCCESS == subjectInfoList.getCode()) {
+                List<CheckSubjectDto> data = subjectInfoList.getData();
+                CheckSubjectDto i = data.get(0);
+                warningNoticeLogDto.setSubId(i.getSubId());
+                warningNoticeLogDto.setSubName(i.getSubjectName());
+                warningNoticeLogDto.setBuildName(i.getBuildName());
+                warningNoticeLogDto.setFloorName(i.getFloorName());
+                warningNoticeLogDto.setFloorName(i.getRoomNumber());
+                userIdStr.append(i.getSafeUserId()).append(",").append(i.getAdminId());
+                phones.append(i.getAdminPhone()).append(",").append(i.getSafeUserPhone());
+            }
+            //todo 记录的人物和实验室 气瓶 需要和申请的人物和实验室 气瓶 等 一一对应 现在无法对应 不能找出借出的气瓶对应的归还时间
+            QpQualificationApplyVO qualificationApply = new QpQualificationApplyVO();
+            qualificationApply.setUserId(QpUseRecord.getUserId());
+            List<QpQualificationApplyVO> qualificationApplies = qualificationApplyService.selectQpQualificationApplyList(qualificationApply);
+            qualificationApplies = qualificationApplies.stream().filter(qa -> qa.getCenterAuditStatus() == 1).filter(qa -> qa.getEndTime().getTime() < Calendar.getInstance().getTime().getTime()).collect(Collectors.toList());
+
+            if(qualificationApplies.size() > 0){
+                //过了最大领用时间
+                String text = "【实验室安全系统】实验室名称-人名领用X气气瓶超时未归还,领用时间:"+LocalDateTime.now().toString()+",请尽快确认。点击查看:http://";
+                warningNoticeLogDto.setWarningContent("化学品超时未归还");
+                String timeout = warningConfigDto.getTimeout();
+                warningNoticeLogDto.setWarningWay(timeout);
+                if (timeout.contains("1")) {
+                    //系统通知
+                    LabMessageContent labMessageContent = new LabMessageContent();
+                    labMessageContent.setSendMode(2);
+                    labMessageContent.setSendRange(3);
+                    labMessageContent.setMessClass(1);
+                    labMessageContent.setMessType(13);
+                    labMessageContent.setSubIds(String.valueOf(QpUseRecord.getSubjectId()));
+                    labMessageContent.setUserIds(userIdStr.toString());
+                    labMessageContent.setContent(text);
+                    remoteMessageContentService.sendMessage(labMessageContent);
+                }
+                if (timeout.contains("2")) {
+                    //短信通知
+                    String[] strings = Stream.of(phones.toString().split(",")).filter(a -> StrUtil.isNotBlank(a)).collect(Collectors.joining(",")).split(",");
+
+                    if (strings != null) {
+                        AlarmEntrty alarmEntrty = new AlarmEntrty(Routes.NoticePush, strings, SendTypes.SMS.toString(), text);
+                        remoteAlarmService.send(alarmEntrty);
+                        log.info("化学品发送短信打电话消息推送完成!");
+                    }
+                }
+            }
+            ResultData resultData = laboratoryService.addWarningNoticeLog(warningNoticeLogDto);
+            if (HttpStatus.SUCCESS == resultData.getCode()) {
+                log.info("气瓶超时未归还保存日志成功!");
+            }
+        });
+    }
 }

+ 7 - 0
zd-modules/zd-airbottle/src/main/java/com/zd/airbottle/service/impl/QpUseRecordServiceImpl.java

@@ -170,6 +170,7 @@ public class QpUseRecordServiceImpl implements IQpUseRecordService {
         }
         //设置其他公共字段
         SaveUtil.setCommonAttr(useRecord);
+        useRecord.setUserStatus(1);
         if (qpUseRecordMapper.insertQpUseRecord(useRecord) >= 1) {
             return result;
         }
@@ -369,4 +370,10 @@ public class QpUseRecordServiceImpl implements IQpUseRecordService {
         taskRVo.setAmount(recordVos.stream().map(QpUseRecordVo::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
         return recordVo.setRecordVos(recordVos).setTaskRVO(taskRVo);
     }
+
+    @Override
+    public List<QpUseRecord> selectNoReturnRecords() {
+        List<QpUseRecord> qpUseRecords = qpUseRecordMapper.selectNoReturnRecords();
+        return qpUseRecords;
+    }
 }

+ 6 - 0
zd-modules/zd-airbottle/src/main/resources/mapper/airbottle/QpUseRecordMapper.xml

@@ -15,6 +15,7 @@
         <result property="afterUsePic" column="after_use_pic"/>
         <result property="afterUse" column="after_use"/>
         <result property="amount" column="amount"/>
+        <result property="userStatus" column="user_status"/>
         <result property="useTime" column="use_time"/>
         <result property="backTime" column="back_time"/>
         <result property="createTime" column="create_time"/>
@@ -36,6 +37,7 @@
                after_use_pic,
                after_use,
                amount,
+               user_status,
                use_time,
                back_time,
                create_time,
@@ -359,5 +361,9 @@
         <include refid="selectQpUseRecordVo"/>
         where id = (select max(id) from qp_use_record where storage_id=#{storageId})
     </select>
+    <select id="selectNoReturnRecords" resultType="com.zd.airbottle.domain.QpUseRecord">
+        <include refid="selectQpUseRecordVo"/>
+        where user_status = 3
+    </select>
 
 </mapper>

+ 1 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/forward/serivce/ImageService.java

@@ -58,6 +58,7 @@ public class ImageService {
                 MultipartFile multipartFile = getMultipartFile(file);
                 R<SysFile> upload = remoteFileService.upload(multipartFile);
                 if (upload.getCode() == HttpStatus.SUCCESS && upload.getData() != null) {
+                    upload.getData().setMultipartFile(multipartFile);
                     return upload.getData();
                 }else {
                     throw new ServerException(upload.getMsg());

+ 11 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/mqtt/MqttConfig.java

@@ -1,8 +1,10 @@
 package com.zd.alg.mqtt;
 
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
 import com.zd.alg.alarm.service.IAlarmLogService;
 import com.zd.alg.alarm.utils.AlarmUtil;
+import com.zd.algorithm.api.alarm.domain.UserPhoneInfo;
 import com.zd.algorithm.api.alarm.entity.AlarmEntrty;
 import com.zd.algorithm.api.alarm.entity.AlarmLog;
 import com.zd.algorithm.api.alarm.entity.Routes;
@@ -32,6 +34,7 @@ import org.springframework.messaging.MessageHandler;
 import org.springframework.messaging.MessagingException;
 
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * mqtt配置
@@ -177,7 +180,10 @@ public class MqttConfig {
                 try {
                     String type = SendTypes.All + "";
                     Map<String, Object> map = JSON.parseObject(msg, Map.class);
+                    Long GroupId = Long.valueOf(String.valueOf(map.get("messageId")));
                     map = JSON.parseObject(map.get("data") + "", Map.class);
+                    List<UserPhoneInfo> userPhoneInfo = JSONArray.parseArray(JSON.toJSONString(map.get("userPhoneInfo")), UserPhoneInfo.class);
+                    LinkedHashMap<String, List<UserPhoneInfo>> userPhoneInfoMap = userPhoneInfo.stream().collect(Collectors.groupingBy(UserPhoneInfo::getPhone, LinkedHashMap::new, Collectors.toList()));
                     String text = (String) map.get("text");
                     List<String> list = JSON.parseArray(map.get("to") + "", String.class);
                     if (CollectionUtils.isEmpty(list)) {
@@ -199,6 +205,7 @@ public class MqttConfig {
                     if ("OK".equals(data)) {
                         String[] phones = alarmEntrty.getTo();
                         for (String phone : phones) {
+                            List<UserPhoneInfo> userPhoneInfos = userPhoneInfoMap.get(phone);
                             AlarmLog alarmLog = new AlarmLog();
                             alarmLog.setRemark("预案ID/实验室ID: " + receivedTopic.replace(defaultTopic, ""));
                             alarmLog.setIsBack(0);
@@ -206,6 +213,10 @@ public class MqttConfig {
                             alarmLog.setPhone(phone);
                             alarmLog.setNotice(alarmEntrty.getText());
                             alarmLog.setCreateTime(DateUtils.getNowDate());
+                            alarmLog.setKeyId(GroupId);
+                            alarmLog.setNickName(userPhoneInfos.get(0).getNickName());
+                            alarmLog.setRole(userPhoneInfos.get(0).getRole());
+                            logger.info("写入数据~~~~~~~~~~~~");
                             alarmLogService.insertAlarmLog(alarmLog);
                         }
                     } else {

+ 1 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/rfid/sdk/RfidClientImpl.java

@@ -35,6 +35,7 @@ public class RfidClientImpl implements IService {
     private static final Map<String, GClient> clientMap = new ConcurrentHashMap<>();
     private static final Map<String, GServer> serverMap = new ConcurrentHashMap<>();
     private static final ScheduledExecutorService scheduledExecutorService = SpringUtils.getBean("scheduledExecutorService");
+
     private static final Integer cacheTime  = 30;
     private static final Integer alarmTime  = 30;
     @Resource

+ 7 - 0
zd-modules/zd-base/src/main/java/com/zd/base/message/controller/WechatMsgController.java

@@ -134,4 +134,11 @@ public class WechatMsgController {
     public R<TemplateResult> sendAlarm(@RequestBody List<Long> userIds, @RequestParam("address") String address) {
         return R.ok(sendService.sendAlarm(userIds,address));
     }
+
+    @GetMapping("/getUrlScheme")
+    @ApiOperation(value = "获取UrlScheme")
+    @ApiImplicitParam(name = "id",value = "传入id",required = false)
+    public ResultData getUrlScheme(@RequestParam(value = "id",required = false)  Long id) {
+        return ResultData.success(sendService.getUrlScheme(id));
+    }
 }

+ 5 - 0
zd-modules/zd-base/src/main/java/com/zd/base/message/properties/WeChatProperties.java

@@ -40,6 +40,11 @@ public class WeChatProperties {
     private String tokenUrl;
 
     /**
+     * 获取微信UrlScheme
+     */
+    private String urlScheme;
+
+    /**
      * 出库确认消息模板ID
      */
     private String storageOutTemplateId;

+ 7 - 0
zd-modules/zd-base/src/main/java/com/zd/base/message/service/IWechatMsgSendService.java

@@ -62,4 +62,11 @@ public interface IWechatMsgSendService {
     TemplateResult sendStuCheckResult(Long userId, Integer checkType, Integer checkStatus, Date checkTime, Long taskId);
 
     TemplateResult sendAlarm(List<Long> userIds,String address);
+
+    /**
+     * 获取getUrlScheme
+     * @param id 小程序端带回的id
+     * @return openId
+     */
+    String getUrlScheme(Long id);
 }

+ 29 - 0
zd-modules/zd-base/src/main/java/com/zd/base/message/service/impl/WechatMsgSendServiceImpl.java

@@ -281,4 +281,33 @@ public class WechatMsgSendServiceImpl implements IWechatMsgSendService {
         }
         return accessToken;
     }
+    /**
+     * 获取UrlScheme
+     * @Param [id]
+     * @Return java.lang.String
+     **/
+    public String getUrlScheme(Long id) {
+        String url = weChatProperties.getUrlScheme()+getAccessToken();
+        //查询是否还有缓存
+        BoundValueOperations<String, String> ops = redisTemplate.boundValueOps("URL_Scheme");
+        //缓存时长
+        if (StringUtils.isBlank(ops.get())) {
+            JSONObject body = new JSONObject();
+            JSONObject jumpWxa = new JSONObject();
+            jumpWxa.put("path","pages/earlyWarningManage/earlyWarningDetail");
+            jumpWxa.put("query",id);
+            body.put("jump_wxa", jumpWxa);
+            String respData = HttpUtil.post(url,body);
+            log.info("get UrlScheme=====\n{}", respData);
+            JSONObject json = JSON.parseObject(respData);
+            if (json.getInteger("errcode") == 0) {
+                String openlink = json.getString("openlink");
+                ops.set(json.getString("openlink"));
+                ops.expire(7100, TimeUnit.SECONDS);
+                return openlink;
+            }
+            return "";
+        }
+        return ops.get();
+    }
 }

+ 2 - 0
zd-modules/zd-chemical/src/main/java/com/zd/chemical/ZdChemicalApplication.java

@@ -14,6 +14,7 @@ import org.springframework.boot.ApplicationArguments;
 import org.springframework.boot.ApplicationRunner;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.context.annotation.ComponentScan;
+import org.springframework.scheduling.annotation.EnableScheduling;
 
 import java.util.Collections;
 import java.util.List;
@@ -22,6 +23,7 @@ import java.util.Optional;
 @EnableCustomConfig
 @EnableZdFeignClients
 @SpringBootApplication
+@EnableScheduling
 @ComponentScan(basePackages = BaseConstants.BASE_PACKAGE)
 public class ZdChemicalApplication implements ApplicationRunner {
 

+ 78 - 0
zd-modules/zd-chemical/src/main/java/com/zd/chemical/config/ThreadPoolTaskConfig.java

@@ -0,0 +1,78 @@
+package com.zd.chemical.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.concurrent.BasicThreadFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.*;
+
+/**
+ * @author Administrator
+ */
+@Configuration
+@Slf4j
+public class ThreadPoolTaskConfig {
+
+    private static final int CORE_POOL_SIZE = 10;
+    private static final int MAX_POOL_SIZE = 100;
+    private static final int KEEP_ALIVE_TIME = 10;
+    private static final int QUEUE_CAPACITY = 200;
+    private static final String THREAD_NAME_PREFIX = "Async-Service-";
+
+    @Bean("taskExecutor")
+    public ThreadPoolTaskExecutor threadPoolTaskExecutor(){
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(CORE_POOL_SIZE);
+        executor.setMaxPoolSize(MAX_POOL_SIZE);
+        executor.setQueueCapacity(QUEUE_CAPACITY);
+        executor.setKeepAliveSeconds(KEEP_ALIVE_TIME);
+        executor.setThreadNamePrefix(THREAD_NAME_PREFIX);
+
+        // 线程池对拒绝任务的处理策略
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        // 初始化
+        executor.initialize();
+        return executor;
+    }
+
+    /**
+     * 执行定时任务
+     */
+    @Bean(name = "scheduledExecutorService")
+    public ScheduledExecutorService scheduledExecutorService() {
+        return new ScheduledThreadPoolExecutor(CORE_POOL_SIZE,
+                new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build()) {
+            @Override
+            protected void afterExecute(Runnable r, Throwable t) {
+                super.afterExecute(r, t);
+                printException(r, t);
+            }
+        };
+    }
+
+
+    /**
+     * 打印线程异常信息
+     */
+    public static void printException(Runnable r, Throwable t) {
+        if (t == null && r instanceof Future<?>) {
+            try {
+                Future<?> future = (Future<?>) r;
+                if (future.isDone()) {
+                    future.get();
+                }
+            } catch (CancellationException ce) {
+                t = ce;
+            } catch (ExecutionException ee) {
+                t = ee.getCause();
+            } catch (InterruptedException ie) {
+                Thread.currentThread().interrupt();
+            }
+        }
+        if (t != null) {
+            log.error(t.getMessage(), t);
+        }
+    }
+}

+ 370 - 20
zd-modules/zd-chemical/src/main/java/com/zd/chemical/service/impl/HxpStockServiceImpl.java

@@ -1,10 +1,16 @@
 package com.zd.chemical.service.impl;
 
+import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.date.LocalDateTimeUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
 import com.zd.algorithm.api.alarm.entity.AlarmEntrty;
 import com.zd.algorithm.api.alarm.entity.Routes;
+import com.zd.algorithm.api.alarm.entity.SendTypes;
 import com.zd.algorithm.api.alarm.feign.RemoteAlarmService;
+import com.zd.algorithm.api.camera.feign.RemoteCameraService;
 import com.zd.algorithm.api.forward.feign.RemoteForwardService;
 import com.zd.algorithm.api.rfid.feign.RemoteRfidService;
 import com.zd.chemical.controller.HxpAIOController;
@@ -12,10 +18,7 @@ import com.zd.chemical.domain.*;
 import com.zd.chemical.domain.vo.*;
 import com.zd.chemical.mapper.*;
 import com.zd.chemical.properties.AlarmProperties;
-import com.zd.chemical.service.IHxpChemicalJoinCabinetService;
-import com.zd.chemical.service.IHxpClassifyConfigService;
-import com.zd.chemical.service.IHxpStockService;
-import com.zd.chemical.service.IHxpUserecordService;
+import com.zd.chemical.service.*;
 import com.zd.chemical.util.ChemicalUtils;
 import com.zd.chemical.util.SmsSydUtil;
 import com.zd.common.core.annotation.DataScope;
@@ -24,14 +27,20 @@ import com.zd.common.core.utils.DateUtils;
 import com.zd.common.core.utils.DictUtils;
 import com.zd.common.core.utils.SaveUtil;
 import com.zd.common.core.utils.SecurityUtils;
+import com.zd.laboratory.api.dto.CheckSubjectDto;
+import com.zd.laboratory.api.dto.WarningConfigDto;
+import com.zd.laboratory.api.dto.WarningNoticeLogDto;
+import com.zd.laboratory.api.entity.LabMessageContent;
+import com.zd.laboratory.api.feign.RemoteLabHardwareService;
 import com.zd.laboratory.api.feign.RemoteLaboratoryService;
 import com.zd.laboratory.api.feign.RemoteMessageContentService;
+import com.zd.model.constant.HttpStatus;
 import com.zd.model.domain.AjaxResult;
 import com.zd.model.domain.R;
+import com.zd.model.domain.ResultData;
 import com.zd.model.domain.per.PerPrefix;
 import com.zd.model.entity.HardwareRfidDto;
 import com.zd.model.entity.InventoryTag;
-import com.zd.model.entity.SysFile;
 import com.zd.system.api.entity.SysDictData;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -39,16 +48,20 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.time.LocalDateTime;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * 库存管理Service业务层处理
@@ -60,6 +73,7 @@ import java.util.concurrent.TimeUnit;
 public class HxpStockServiceImpl implements IHxpStockService {
     private static Logger logger = LoggerFactory.getLogger(HxpStockServiceImpl.class);
 
+//    private static final ScheduledExecutorService scheduledExecutorService = SpringUtils.getBean("scheduledExecutorService");
     private static Map<String, Date> cacheMap = new ConcurrentHashMap<>();
 
     private static int interval = 60 * 3;
@@ -113,6 +127,15 @@ public class HxpStockServiceImpl implements IHxpStockService {
     private AlarmProperties alarmProperties;
     @Resource
     private RemoteForwardService remoteForwardService;
+    @Resource
+    private RemoteLabHardwareService remoteLabHardwareService;
+    @Resource
+    private RemoteCameraService remoteCameraService;
+    @Resource
+    private ScheduledExecutorService scheduledExecutorService;
+    @Autowired
+    private IHxpChemicalService hxpChemicalService;
+
     /**
      * 查询库存管理
      *
@@ -344,6 +367,7 @@ public class HxpStockServiceImpl implements IHxpStockService {
             logger.info("RFID 实时检测 (标签未绑定化学品): " + rfidCode);
             return false;
         }
+        HxpChemicalJoinCabinet hxpChemicalJoinCabinet = hxpCabinetJoinCabinetService.selectHxpChemicalJoinCabinetById(hxpStock.getJoinId());
 
         // 查询该库存数据是否处于领用状态
         HxpUserecord hxpUserecord = hxpUserecordMapper.selectByStockId(hxpStock.getId());
@@ -352,24 +376,95 @@ public class HxpStockServiceImpl implements IHxpStockService {
             return false;
         }else {
             logger.info("RFID 检测到违规触发报警: " + JSONUtil.toJsonStr(hxpStock));
-            String streamUrl = alarmProperties.getStreamUrl();
-            R<SysFile> fileR = null;
-            if (org.springframework.util.StringUtils.hasLength(streamUrl)){
-                fileR= remoteForwardService.photograph(alarmProperties.getStreamUrl());
-            }
-            if (fileR!=null){
-                logger.info("文件上传状态:{},接口返回消息:{},文件上传路径:{}",fileR.getCode(),fileR.getMsg(),fileR.getData());
-            }
             //触发RFID警报
             HardwareRfidDto hardwareRfidDto = tag.getHardwareRfidDto();
             boolean isAlarm = false;
-            if (hardwareRfidDto!=null){
-                R<Boolean> alarm = remoteRfidService.alarm(hardwareRfidDto);//RFID设备报警
-                logger.info("==================>{},{}",alarm.getCode(),alarm.getMsg());
-                //isAlarm = true;
-            }else {
-                logger.info("==================> rfid 参数有误!"+ tag.toString());
-            }
+                // 查询配置
+                ResultData<WarningConfigDto> byType = remoteLaboratoryService.getByType(2);
+                if (HttpStatus.SUCCESS != byType.getCode()) {
+                    return false;
+                }
+                //违规带离(1系统通知 2短信通知 3声光报警)
+                WarningConfigDto warningConfigDto = byType.getData();
+                String illegalRemoval = warningConfigDto.getIllegalRemoval();
+
+                WarningNoticeLogDto warningNoticeLogDto = new WarningNoticeLogDto();
+                warningNoticeLogDto.setKeyId(hxpStock.getId());
+                warningNoticeLogDto.setName(hxpStock.getChemicalName());
+                warningNoticeLogDto.setWarningType(2);
+                warningNoticeLogDto.setWarningSubType(1);
+                warningNoticeLogDto.setWarningContent("化学品违规带离");
+                warningNoticeLogDto.setWarningTime(LocalDateTime.now());
+                warningNoticeLogDto.setWarningWay(illegalRemoval);
+                warningNoticeLogDto.setMargin(hxpStock.getOutUsages());
+                warningNoticeLogDto.setDeposit(hxpStock.getCabinetName());
+                warningNoticeLogDto.setSpecification(hxpChemicalJoinCabinet.getChemicalAmount() + hxpChemicalJoinCabinet.getChemicalAmountUnit());
+
+                //查询到实验室负责人id 安全责任人id
+                ResultData<List<CheckSubjectDto>> subjectInfoList = remoteLaboratoryService.findSubjectInfoList(String.valueOf(hxpStock.getSubId()));
+                StringBuffer userIdStr = new StringBuffer();
+                StringBuffer phones = new StringBuffer();
+                if (HttpStatus.SUCCESS == subjectInfoList.getCode()) {
+                    List<CheckSubjectDto> data = subjectInfoList.getData();
+                    CheckSubjectDto i = data.get(0);
+                    warningNoticeLogDto.setSubId(i.getSubId());
+                    warningNoticeLogDto.setSubName(i.getSubjectName());
+                    warningNoticeLogDto.setBuildName(i.getBuildName());
+                    warningNoticeLogDto.setFloorName(i.getFloorName());
+                    warningNoticeLogDto.setRoomNum(i.getRoomNumber());
+                    userIdStr.append(i.getSafeUserId()).append(",").append(i.getAdminId());
+                    phones.append(i.getAdminPhone()).append(",").append(i.getSafeUserPhone());
+                }
+                ResultData resultData = remoteLaboratoryService.addWarningNoticeLog(warningNoticeLogDto);
+                if (HttpStatus.SUCCESS != resultData.getCode()) {
+                    return false;
+                }
+                Long logId = (Long)resultData.getData();
+                if(illegalRemoval != null){
+                    String text = "【实验室安全系统】实验室名称-实验人员违规携带化学品名称离开房间,发生时间:"+LocalDateTimeUtil.format(LocalDateTime.now(),"yyyy-MM-dd HH:mm:ss")+",请尽快确认。点击查看:http://";
+                    if (illegalRemoval.contains("1")) {
+                        //系统通知
+                        LabMessageContent labMessageContent = new LabMessageContent();
+                        labMessageContent.setSendMode(2);
+                        labMessageContent.setSendRange(3);
+                        labMessageContent.setMessClass(1);
+                        labMessageContent.setMessType(13);
+                        labMessageContent.setSubIds(String.valueOf(hxpStock.getSubId()));
+                        labMessageContent.setUserIds(userIdStr.toString());
+                        labMessageContent.setContent(text);
+                        remoteMessageContentService.sendMessage(labMessageContent);
+
+                    }
+                    if (illegalRemoval.contains("2")) {
+                        //短信通知
+                        String[] strings = Stream.of(phones.toString().split(","))
+                                .filter(a -> StrUtil.isNotBlank(a))
+                                .collect(Collectors.joining(","))
+                                .split(",");
+
+                        if (strings != null) {
+                            AlarmEntrty alarmEntrty = new AlarmEntrty(Routes.NoticePush, strings, SendTypes.SMS.toString(),text);
+                            remoteAlarmService.send(alarmEntrty);
+                            logger.info("气瓶发送短信打电话消息推送完成!");
+                        }
+                    }
+                    if (hardwareRfidDto!=null && illegalRemoval.contains("3")) {
+                        //声光报警
+                        R<Boolean> alarm = remoteRfidService.alarm(hardwareRfidDto);
+                        logger.info("==================>{},{}",alarm.getCode(),alarm.getMsg());
+                    }
+                    ResultData result = remoteLabHardwareService.findCameraByType(hxpStock.getSubId(), 4, 2);
+                    if (HttpStatus.SUCCESS == result.getCode()) {
+                        String ip = String.valueOf(result.getData());
+                        startVideo(ip);
+                        scheduledExecutorService.schedule(new TimerTask() {
+                            @Override
+                            public void run() {
+                                stopVideo(ip,logId);
+                            }
+                        }, 30, TimeUnit.SECONDS);
+                    }
+                }
             // 如果非领用状态,做报警台账
             // 0.检测实验室声光报警器是否使用- 使用则直接调用触发- 否则跳过
             Map<String,Object> subInfo = hxpUserecordMapper.selectSubInfoById(hxpStock.getSubId());
@@ -497,6 +592,35 @@ public class HxpStockServiceImpl implements IHxpStockService {
         }
     }
 
+    private void startVideo(String cameraIpAddress) {
+        if(org.apache.commons.lang3.StringUtils.isNotBlank(cameraIpAddress)){
+            R r = remoteCameraService.startRecord(cameraIpAddress);
+            logger.info("报警模块-开始录制视频返回结果打印={}", JSON.toJSONString(r));
+            if (r.getCode() == HttpStatus.SUCCESS) {
+                logger.info("报警模块-开始录制视频成功!");
+            } else {
+                logger.info("报警模块-开始录制视频失败!");
+            }
+        }else {
+            logger.info("报警模块-摄像头ip为空!");
+        }
+    }
+    private void stopVideo(String cameraIpAddress,Long logId) {
+        if(org.apache.commons.lang3.StringUtils.isNotBlank(cameraIpAddress)){
+            R r = remoteCameraService.stopRecord(cameraIpAddress);
+            logger.info("报警模块-录制视频结束返回结果打印={}", JSON.toJSONString(r));
+            if (r.getCode() == HttpStatus.SUCCESS) {
+                String recordVideo = String.valueOf(r.getData());
+                WarningNoticeLogDto warningNoticeLogDto = new WarningNoticeLogDto();
+                warningNoticeLogDto.setId(logId);
+                warningNoticeLogDto.setRecordVideo(recordVideo);
+                remoteLaboratoryService.updateWarningNoticeLog(warningNoticeLogDto);
+            } else {
+                logger.info("报警模块-结束录制视频失败!");
+            }
+        }
+    }
+
     private Long sendPhoneAlarm(Long stockId, Long subId, String subName, String chemicalName, String phones) {
 
         try {
@@ -763,4 +887,230 @@ public class HxpStockServiceImpl implements IHxpStockService {
             hxpCabinetlockLogMapper.updateHxpCabinetlockLog(hxpCabinetlockLog);
         }
     }
+
+    /**
+     * 化学品已过期 化学品即将过期
+     *
+     * @Param []
+     * @Return void
+     **/
+
+    @Scheduled(cron = "0 0 0 * * ?")
+//    @Scheduled(cron = "0 0/1 * * * ? ")
+    public void hxpExpired() {
+        //之前代码
+        //expireCheck();
+
+        // 查询配置
+        ResultData<WarningConfigDto> byType = remoteLaboratoryService.getByType(2);
+        if (HttpStatus.SUCCESS != byType.getCode()) {
+            logger.info("未查询到相关配置!");
+            return;
+        }
+        //违规带离(1系统通知 2短信通知 3声光报警)
+        WarningConfigDto warningConfigDto = byType.getData();
+        //化学品已过期 化学品即将过期
+        List<HxpStock> hxpStocks = hxpStockMapper.selectHxpStockList(new HxpStock());
+        Optional.ofNullable(hxpStocks).orElseGet(Collections::emptyList).forEach(hxpStock -> {
+            //过期时间
+            Date expirationTime = hxpStock.getExpirationTime();
+            //即将过期提醒天数
+            Integer unexpiredWarnDays = warningConfigDto.getUnexpiredWarnDays();
+            DateTime startDateTime = DateUtil.offsetDay(DateTime.now(), unexpiredWarnDays);
+            DateTime endDateTime = DateUtil.offsetDay(DateTime.now(), unexpiredWarnDays + 1);
+
+            ResultData resultData = remoteLaboratoryService.getRemindData(hxpStock.getId());
+            if (HttpStatus.SUCCESS != resultData.getCode()) {
+                logger.error("获取提醒日志数据失败!");
+            }
+            List<WarningNoticeLogDto> warningNoticeLogDtos = JSON.parseArray(JSON.toJSONString(resultData.getData()), WarningNoticeLogDto.class);
+            //过期提醒数据
+            List<WarningNoticeLogDto> logDtoList = Optional.ofNullable(warningNoticeLogDtos).orElseGet(Collections::emptyList).stream().filter(i -> i.getWarningType() == 2 && i.getWarningSubType() == 4).collect(Collectors.toList());
+
+            //过期时间在提醒天数内 并且在一天之内
+            WarningNoticeLogDto warningNoticeLogDto = new WarningNoticeLogDto();
+            warningNoticeLogDto.setKeyId(hxpStock.getId());
+            warningNoticeLogDto.setName(hxpStock.getChemicalName());
+            warningNoticeLogDto.setWarningType(2);
+            warningNoticeLogDto.setWarningTime(LocalDateTime.now());
+            //TODO 余量
+            warningNoticeLogDto.setMargin(BigDecimal.ZERO);
+            warningNoticeLogDto.setSpecification(String.valueOf(hxpStock.getChemicalAmount()));
+
+            //查询到实验室负责人id 安全责任人id
+            ResultData<List<CheckSubjectDto>> subjectInfoList = remoteLaboratoryService.findSubjectInfoList(String.valueOf(hxpStock.getSubId()));
+            StringBuffer userIdStr = new StringBuffer();
+            StringBuffer phones = new StringBuffer();
+            if (HttpStatus.SUCCESS == subjectInfoList.getCode()) {
+                List<CheckSubjectDto> data = subjectInfoList.getData();
+                CheckSubjectDto i = data.get(0);
+                warningNoticeLogDto.setSubId(i.getSubId());
+                warningNoticeLogDto.setSubName(i.getSubjectName());
+                warningNoticeLogDto.setBuildName(i.getBuildName());
+                warningNoticeLogDto.setFloorName(i.getFloorName());
+                warningNoticeLogDto.setFloorName(i.getRoomNumber());
+                userIdStr.append(i.getSafeUserId()).append(",").append(i.getAdminId());
+                phones.append(i.getAdminPhone()).append(",").append(i.getSafeUserPhone());
+            }
+            //即将过期
+            if (startDateTime.getTime() < expirationTime.getTime() && endDateTime.getTime() > expirationTime.getTime()) {
+                String text = "【实验室安全系统】实验室名称-化学品名称即将过期,发生时间:" + LocalDateTime.now() + ",请尽快确认。点击查看:http://";
+                warningNoticeLogDto.setWarningContent("化学品即将过期");
+                warningNoticeLogDto.setWarningSubType(3);
+                String unexpired = warningConfigDto.getUnexpired();
+                warningNoticeLogDto.setWarningWay(unexpired);
+                if (unexpired.contains("1")) {
+                    //系统通知
+                    LabMessageContent labMessageContent = new LabMessageContent();
+                    labMessageContent.setSendMode(2);
+                    labMessageContent.setSendRange(3);
+                    labMessageContent.setMessClass(1);
+                    labMessageContent.setMessType(13);
+                    labMessageContent.setSubIds(String.valueOf(hxpStock.getSubId()));
+                    labMessageContent.setUserIds(userIdStr.toString());
+                    labMessageContent.setContent(text);
+                    remoteMessageContentService.sendMessage(labMessageContent);
+
+                }
+                if (unexpired.contains("2")) {
+                    //短信通知
+                    String[] strings = Stream.of(phones.toString().split(",")).filter(a -> StrUtil.isNotBlank(a)).collect(Collectors.joining(",")).split(",");
+                    if (strings != null) {
+                        AlarmEntrty alarmEntrty = new AlarmEntrty(Routes.NoticePush, strings, SendTypes.SMS.toString(), text);
+                        remoteAlarmService.send(alarmEntrty);
+                        logger.info("化学品发送短信打电话消息推送完成!");
+                    }
+                }
+                ResultData result = remoteLaboratoryService.addWarningNoticeLog(warningNoticeLogDto);
+                if (HttpStatus.SUCCESS == result.getCode()) {
+                    logger.info("即将过期保存日志成功!");
+                }
+            }
+            //已过期
+            if (DateUtils.getNowDate().getTime() >= expirationTime.getTime() && logDtoList.size() <= warningConfigDto.getExpiredWarnCount()) {
+                String text2 = "【实验室安全系统】实验室名称-化学品名称已过期,请尽快确认。点击查看:http://";
+                warningNoticeLogDto.setWarningContent("化学品已过期");
+                warningNoticeLogDto.setWarningSubType(4);
+                String expired = warningConfigDto.getExpired();
+                warningNoticeLogDto.setWarningWay(expired);
+                if (expired.contains("1")) {
+                    //系统通知
+                    LabMessageContent labMessageContent = new LabMessageContent();
+                    labMessageContent.setSendMode(2);
+                    labMessageContent.setSendRange(3);
+                    labMessageContent.setMessClass(1);
+                    labMessageContent.setMessType(13);
+                    labMessageContent.setSubIds(String.valueOf(hxpStock.getSubId()));
+                    labMessageContent.setUserIds(userIdStr.toString());
+                    labMessageContent.setContent(text2);
+                    remoteMessageContentService.sendMessage(labMessageContent);
+                }
+                if (expired.contains("2")) {
+                    //短信通知
+                    String[] strings = Stream.of(phones.toString().split(",")).filter(a -> StrUtil.isNotBlank(a)).collect(Collectors.joining(",")).split(",");
+                    if (strings != null) {
+                        AlarmEntrty alarmEntrty = new AlarmEntrty(Routes.NoticePush, strings, SendTypes.SMS.toString(), text2);
+                        remoteAlarmService.send(alarmEntrty);
+                        logger.info("化学品发送短信打电话消息推送完成!");
+                    }
+                }
+                ResultData result = remoteLaboratoryService.addWarningNoticeLog(warningNoticeLogDto);
+                if (HttpStatus.SUCCESS == result.getCode()) {
+                    logger.info("已过期保存日志成功!");
+                }
+            }
+        });
+    }
+    /**
+     * 化学品超时未归还
+     * @Param []
+     * @Return void
+     **/
+//    @Scheduled(cron = "0 0/1 * * * ? ")
+    @Scheduled(cron = "0 0 0 * * ?")
+    public void hxpTimeOut() {
+        // 查询配置
+        ResultData<WarningConfigDto> byType = remoteLaboratoryService.getByType(2);
+        if (HttpStatus.SUCCESS != byType.getCode()) {
+            logger.info("未查询到相关配置!");
+            return;
+        }
+        WarningConfigDto warningConfigDto = byType.getData();
+        //化学品超时未归还
+        List hxpIds = new ArrayList<>();
+        List<HxpUserecord> hxpUserecordList = hxpUserecordMapper.selectByOvertime();
+
+        Optional.ofNullable(hxpUserecordList).orElseGet(Collections::emptyList).forEach(hxpUserecord -> {
+            HxpStock hxpStock = hxpStockMapper.selectHxpStockById(hxpUserecord.getStockId());
+            AioChemicalVo aioChemicalVo = new AioChemicalVo();
+            aioChemicalVo.setCabinetId(hxpStock.getCabinetId());
+            HxpChemicalJoinCabinet hxpChemicalJoinCabinet = hxpChemicalJoinCabinetMapper.selectHxpChemicalJoinCabinetById(hxpStock.getJoinId());
+            HxpChemical hxpChemical = hxpChemicalService.selectHxpChemicalById(hxpChemicalJoinCabinet.getId());
+            Integer collectHour = hxpChemical.getCollectHour();
+            Integer collectMinute = hxpChemical.getCollectMinute();
+            Integer minute = collectHour * 60 + collectMinute;
+            DateTime dateTime = DateUtil.offsetMinute(hxpUserecord.getCollectTime(), minute);
+
+            //过期时间在提醒天数内 并且在一天之内
+            WarningNoticeLogDto warningNoticeLogDto = new WarningNoticeLogDto();
+            warningNoticeLogDto.setKeyId(hxpStock.getId());
+            warningNoticeLogDto.setName(hxpStock.getChemicalShapeName());
+            warningNoticeLogDto.setWarningType(2);
+            warningNoticeLogDto.setWarningTime(LocalDateTime.now());
+            //TODO 余量
+            warningNoticeLogDto.setMargin(BigDecimal.ZERO);
+            warningNoticeLogDto.setSpecification(String.valueOf(hxpStock.getChemicalAmount()));
+
+            //查询到实验室负责人id 安全责任人id
+            ResultData<List<CheckSubjectDto>> subjectInfoList = remoteLaboratoryService.findSubjectInfoList(String.valueOf(hxpStock.getSubId()));
+            StringBuffer userIdStr = new StringBuffer();
+            StringBuffer phones = new StringBuffer();
+            if (HttpStatus.SUCCESS == subjectInfoList.getCode()) {
+                List<CheckSubjectDto> data = subjectInfoList.getData();
+                CheckSubjectDto i = data.get(0);
+                warningNoticeLogDto.setSubId(i.getSubId());
+                warningNoticeLogDto.setSubName(i.getSubjectName());
+                warningNoticeLogDto.setBuildName(i.getBuildName());
+                warningNoticeLogDto.setFloorName(i.getFloorName());
+                warningNoticeLogDto.setFloorName(i.getRoomNumber());
+                userIdStr.append(i.getSafeUserId()).append(",").append(i.getAdminId());
+                phones.append(i.getAdminPhone()).append(",").append(i.getSafeUserPhone());
+            }
+            if(DateUtils.getNowDate().getTime() > dateTime.getTime()){
+                hxpIds.add(hxpUserecord.getId());
+                //过了最大领用时间
+                String text = "【实验室安全系统】实验室名称-人名领用化学品名称超时未归还,领用时间:"+LocalDateTime.now().toString() +",请尽快确认。点击查看:http://";
+                warningNoticeLogDto.setWarningContent("化学品超时未归还");
+                warningNoticeLogDto.setWarningSubType(2);
+                String timeout = warningConfigDto.getTimeout();
+                warningNoticeLogDto.setWarningWay(timeout);
+                if (timeout.contains("1")) {
+                    //系统通知
+                    LabMessageContent labMessageContent = new LabMessageContent();
+                    labMessageContent.setSendMode(2);
+                    labMessageContent.setSendRange(3);
+                    labMessageContent.setMessClass(1);
+                    labMessageContent.setMessType(13);
+                    labMessageContent.setSubIds(String.valueOf(hxpStock.getSubId()));
+                    labMessageContent.setUserIds(userIdStr.toString());
+                    labMessageContent.setContent(text);
+                    remoteMessageContentService.sendMessage(labMessageContent);
+                }
+                if (timeout.contains("2")) {
+                    //短信通知
+                    String[] strings = Stream.of(phones.toString().split(",")).filter(a -> StrUtil.isNotBlank(a)).collect(Collectors.joining(",")).split(",");
+                    if (strings != null) {
+                        AlarmEntrty alarmEntrty = new AlarmEntrty(Routes.NoticePush, strings, SendTypes.SMS.toString(), text);
+                        remoteAlarmService.send(alarmEntrty);
+                        logger.info("化学品发送短信打电话消息推送完成!");
+                    }
+                }
+            }
+            ResultData result = remoteLaboratoryService.addWarningNoticeLog(warningNoticeLogDto);
+            if (HttpStatus.SUCCESS == result.getCode()) {
+                logger.info("化学品超时未归还保存日志成功!");
+            }
+        });
+        hxpUserecordMapper.updateUserecordOvertimeByIds(hxpIds);
+    }
 }

+ 43 - 4
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/controller/LabHardwareController.java

@@ -15,14 +15,12 @@ import com.zd.common.core.web.controller.BaseController;
 import com.zd.laboratory.api.entity.FunctionStatus;
 import com.zd.laboratory.api.vo.HardwareCVO;
 import com.zd.laboratory.domain.LabHardware;
+import com.zd.laboratory.domain.LabHazardSubjectRelation;
 import com.zd.laboratory.domain.XxpCardInfo;
 import com.zd.laboratory.domain.vo.HxpSmartTerminalByExcel;
 import com.zd.laboratory.domain.vo.LabHardwareVO;
 import com.zd.laboratory.domain.vo.LabSensorVO;
-import com.zd.laboratory.service.ILabHardwareService;
-import com.zd.laboratory.service.ILabSensorService;
-import com.zd.laboratory.service.ILabSubjectService;
-import com.zd.laboratory.service.IXxpCardInfoService;
+import com.zd.laboratory.service.*;
 import com.zd.laboratory.service.impl.LabSubjectManagerService;
 import com.zd.laboratory.socket.command.Symbol;
 import com.zd.model.constant.HttpStatus;
@@ -36,6 +34,7 @@ import com.zd.model.entity.RemoteLabHardware;
 import com.zd.model.enums.HardwareOperate;
 import com.zd.model.enums.HardwareTypeEnum;
 import com.zd.model.page.TableDataInfo;
+import com.zd.system.api.entity.CommonCount;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -80,6 +79,9 @@ public class LabHardwareController extends BaseController {
     @Autowired
     private IXxpCardInfoService xxpCardInfoService;
 
+    @Autowired
+    private ILabHazardSubjectRelationService labHazardSubjectRelationService;
+
     /**
      * 查询硬件统计
      * @return
@@ -506,4 +508,41 @@ public class LabHardwareController extends BaseController {
         String hardwardStr = labHardwareService.selectLabHardwareCameraBySubId(subId);
         return ResultData.success(hardwardStr);
     }
+
+    /**
+     * 根据类型查询摄像头信息
+     * @Param [subId 实验室id,
+     *          type 设备类型(0,一体机 1,电源开关 2 智能通风,3,语音对讲,4,视频监控5,智能终端 6,智能门锁 ,7,RFID识别器,8,智能报警器,9,智能柜锁,11 海康门禁),
+     *          pcType 摄像头类型:(0普通摄像头 1抓拍摄像头 2违规带离摄像头)]
+     * @Return com.zd.model.domain.ResultData
+     **/
+    @RequestMapping("/findCameraByType")
+    public ResultData findCameraByType(@RequestParam("subId") Long subId,
+                                       @RequestParam("type") Integer type,
+                                       @RequestParam("pcType") Integer pcType) {
+        LabHardware labHardware = labHardwareService.findCameraByType(subId, type, pcType);
+        return ResultData.success(labHardware.getIpAddress());
+    }
+
+    /***
+     * 根据实验室id查询危险源
+     * @param subjectId
+     * @return
+     */
+    @RequestMapping("/getBySubjectId")
+    public List<LabHazardSubjectRelation>  getBySubjectId(@RequestParam("subjectId") Long subjectId) {
+        List<LabHazardSubjectRelation> list= labHazardSubjectRelationService.queryBySubjectId(subjectId);
+        return list;
+    }
+
+    /***
+     * 根据实验室id集合查询危险源数量
+     * @param ids
+     * @return
+     */
+    @RequestMapping("/getBySubjectIds")
+    public List<CommonCount>  getBySubjectIds(@RequestParam("ids") Long... ids) {
+        List<CommonCount> list= labHazardSubjectRelationService.queryCountBySubIds(ids);
+        return list;
+    }
 }

+ 59 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/controller/WarningConfigController.java

@@ -0,0 +1,59 @@
+package com.zd.laboratory.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.zd.common.core.utils.BeanUtils;
+import com.zd.common.core.web.controller.AbstractController;
+import com.zd.laboratory.api.dto.WarningConfigDto;
+import com.zd.laboratory.domain.WarningConfig;
+import com.zd.laboratory.mqtt.service.impl.CommonSend;
+import com.zd.laboratory.service.WarningConfigService;
+import com.zd.model.domain.ResultData;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 预警配置表 前端控制器
+ * </p>
+ *
+ * @author hzw
+ * @since 2023-06-13
+ */
+@RestController
+@RequestMapping("/warningConfig")
+public class WarningConfigController extends AbstractController {
+    @Autowired
+    private WarningConfigService warningConfigService;
+
+    @Autowired
+    CommonSend commonSend;
+
+    @PostMapping("/addOrUpdate")
+    @ApiOperation("新增/修改报警配置")
+    public ResultData addOrUpdate(@RequestBody List<WarningConfig> warningConfigs) {
+        boolean b = warningConfigService.saveOrUpdateBatch(warningConfigs);
+        if (b) {
+            return ResultData.success();
+        }
+        return ResultData.fail();
+    }
+
+    @GetMapping("/list")
+    @ApiOperation("查询报警配置列表")
+    public ResultData getList(@RequestParam(value = "warningType") String warningType) {
+        List<WarningConfig> list = warningConfigService.list(new LambdaQueryWrapper<WarningConfig>().in(WarningConfig::getWarningType,warningType.split(",")).orderByDesc(WarningConfig::getId));
+        return ResultData.success(list);
+    }
+
+    @GetMapping("/getByType")
+    @ApiOperation("根据类型查询报警配置信息")
+    public ResultData<WarningConfigDto> getByType(@RequestParam("type") Integer type) {
+        WarningConfig warningConfig = warningConfigService.getOne(new LambdaQueryWrapper<WarningConfig>().eq(WarningConfig::getWarningType, type));
+        WarningConfigDto warningConfigDto = new WarningConfigDto();
+        BeanUtils.copyProperties(warningConfig, warningConfigDto);
+        return ResultData.success(warningConfigDto);
+    }
+}

+ 19 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/controller/WarningDetailController.java

@@ -0,0 +1,19 @@
+package com.zd.laboratory.controller;
+
+import com.zd.common.core.web.controller.AbstractController;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 预警详情表 前端控制器
+ * </p>
+ *
+ * @author hzw
+ * @since 2023-06-16
+ */
+@RestController
+@RequestMapping("/warningDetail")
+public class WarningDetailController extends AbstractController {
+
+}

+ 117 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/controller/WarningNoticeLogController.java

@@ -0,0 +1,117 @@
+package com.zd.laboratory.controller;
+
+import cn.hutool.core.date.LocalDateTimeUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zd.common.core.utils.StringUtils;
+import com.zd.common.core.web.controller.AbstractController;
+import com.zd.laboratory.api.dto.WarningNoticeLogDto;
+import com.zd.laboratory.domain.WarningNoticeLog;
+import com.zd.laboratory.domain.dto.QueryAppWarningLogParam;
+import com.zd.laboratory.domain.dto.QueryWarningLogParam;
+import com.zd.laboratory.domain.vo.WarningNoticeLogVO;
+import com.zd.laboratory.service.WarningNoticeLogService;
+import com.zd.model.domain.ResultData;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * 预警通知日志 前端控制器
+ * </p>
+ *
+ * @author hzw
+ * @since 2023-06-13
+ */
+@RestController
+@RequestMapping("/warningNoticeLog")
+public class WarningNoticeLogController extends AbstractController {
+
+    @Autowired
+    private WarningNoticeLogService warningNoticeLogService;
+
+    @PostMapping("/add")
+    @ApiOperation("新增报警记录日志")
+    public ResultData add(@RequestBody WarningNoticeLogDto warningNoticeLogDto){
+        WarningNoticeLog warningNoticeLog = new WarningNoticeLog();
+        BeanUtils.copyProperties(warningNoticeLogDto,warningNoticeLog);
+        Long logId = warningNoticeLogService.addWarningNoticeLog(warningNoticeLog);
+        if (logId > 0) {
+            return ResultData.success(logId);
+        }
+        return ResultData.fail();
+    }
+
+    @PostMapping("/update")
+    @ApiOperation("修改报警记录日志")
+    public ResultData update(@RequestBody WarningNoticeLogDto warningNoticeLogDto){
+        WarningNoticeLog warningNoticeLog = new WarningNoticeLog();
+        BeanUtils.copyProperties(warningNoticeLogDto,warningNoticeLog);
+        boolean b = warningNoticeLogService.updateById(warningNoticeLog);
+        if (b) {
+            return ResultData.success();
+        }
+        return ResultData.fail();
+    }
+
+    @PostMapping("/list")
+    @ApiOperation("查询预警通知列表")
+    public ResultData list(@RequestBody QueryWarningLogParam queryWarningLogParam){
+        LambdaQueryWrapper<WarningNoticeLog> queryWrapper = new LambdaQueryWrapper<>();
+        if(queryWarningLogParam.getWarningType() != null && queryWarningLogParam.getWarningType() != 0){
+            queryWrapper.eq(WarningNoticeLog::getWarningType, queryWarningLogParam.getWarningType());
+        }
+        if(queryWarningLogParam.getWarningStartTime() != null && queryWarningLogParam.getWarningEndTime() != null){
+            queryWrapper.between(WarningNoticeLog::getWarningTime, queryWarningLogParam.getWarningStartTime(),queryWarningLogParam.getWarningEndTime());
+        }
+        if(StringUtils.isNotBlank(queryWarningLogParam.getWarningWay())){
+            queryWrapper.in(WarningNoticeLog::getWarningWay, queryWarningLogParam.getWarningWay());
+        }
+        queryWrapper.orderByDesc(WarningNoticeLog::getId);
+        Page page = warningNoticeLogService.page(new Page(queryWarningLogParam.getPageNum(), queryWarningLogParam.getPageSize()), queryWrapper);
+        return ResultData.success(page);
+    }
+
+    @PostMapping("/appList")
+    @ApiOperation("小程序查询预警通知列表")
+    public ResultData appList(QueryAppWarningLogParam queryAppWarningLogParam){
+        Page<LinkedHashMap<LocalDate, List<WarningNoticeLogVO>>> VOPage = new Page<LinkedHashMap<LocalDate, List<WarningNoticeLogVO>>>();
+        Page<WarningNoticeLog> page = warningNoticeLogService.page(new Page<WarningNoticeLog>(queryAppWarningLogParam.getPageNum(), queryAppWarningLogParam.getPageSize()), new LambdaQueryWrapper<WarningNoticeLog>().orderByDesc(WarningNoticeLog::getCreateTime));
+        List<WarningNoticeLog> records = page.getRecords();
+        if (records.size() > 0) {
+            List<WarningNoticeLogVO> warningNoticeLogVOS = com.zd.common.core.utils.BeanUtils.copyList2List(records, WarningNoticeLogVO.class);
+            warningNoticeLogVOS.forEach(warningNoticeLogVO -> {
+                warningNoticeLogVO.setCreateDate(LocalDateTimeUtil.ofDate(warningNoticeLogVO.getCreateTime()));
+            });
+            List<LinkedHashMap<LocalDate, List<WarningNoticeLogVO>>> list = new ArrayList<>();
+            LinkedHashMap<LocalDate, List<WarningNoticeLogVO>> collect = warningNoticeLogVOS.stream().collect(Collectors.groupingBy(WarningNoticeLogVO::getCreateDate, LinkedHashMap::new, Collectors.toList()));
+            list.add(collect);
+            BeanUtils.copyProperties(page,VOPage);
+            VOPage.setRecords(list);
+        }
+        return ResultData.success(VOPage);
+    }
+
+    @GetMapping("/getById")
+    @ApiOperation("根据id查询日志详情")
+    public ResultData getById(@RequestParam("id") Long id){
+        WarningNoticeLogVO warningNoticeLogVO = warningNoticeLogService.getLogById(id);
+        return ResultData.success(warningNoticeLogVO);
+    }
+
+    @GetMapping("/getRemindData")
+    @ApiOperation("根据keyId获取过期提醒次数")
+    public ResultData getRemindData(@RequestParam("keyId") Long keyId) {
+        List<WarningNoticeLog> list = warningNoticeLogService.list(new LambdaQueryWrapper<WarningNoticeLog>().eq(WarningNoticeLog::getKeyId, keyId));
+        List<WarningNoticeLogDto> warningNoticeLogDtos = com.zd.common.core.utils.BeanUtils.copyList2List(list, WarningNoticeLogDto.class);
+        return ResultData.success(warningNoticeLogDtos);
+    }
+}

+ 17 - 8
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/LabWarnPushMessage.java

@@ -2,7 +2,6 @@ package com.zd.laboratory.domain;
 
 import com.zd.model.annotation.Excel;
 import com.zd.model.entity.BaseEntity;
-import com.zd.model.enums.WarnMessageTypeEnum;
 import com.zd.model.enums.WarnUserAttrEnum;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -34,7 +33,7 @@ public class LabWarnPushMessage extends BaseEntity
     /** 推送类型0:语音 1:短信 */
     @Excel(name = "推送类型0:语音 1:短信")
     @ApiModelProperty(value = "推送类型0:语音 1:短信")
-    private WarnMessageTypeEnum pushType;
+    private Integer pushType;
     /** 预警ID */
     @Excel(name = "预警ID")
     @ApiModelProperty(value = "预警ID")
@@ -78,15 +77,25 @@ public class LabWarnPushMessage extends BaseEntity
     {
         return context;
     }
-    public void setPushType(WarnMessageTypeEnum pushType)
-    {
-        this.pushType = pushType;
-    }
+//    public void setPushType(WarnMessageTypeEnum pushType)
+//    {
+//        this.pushType = pushType;
+//    }
+//
+//    public WarnMessageTypeEnum getPushType()
+//    {
+//        return pushType;
+//    }
 
-    public WarnMessageTypeEnum getPushType()
-    {
+
+    public Integer getPushType() {
         return pushType;
     }
+
+    public void setPushType(Integer pushType) {
+        this.pushType = pushType;
+    }
+
     public void setWarnId(Long warnId)
     {
         this.warnId = warnId;

+ 107 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/WarningConfig.java

@@ -0,0 +1,107 @@
+package com.zd.laboratory.domain;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 预警配置表
+ * </p>
+ *
+ * @author hzw
+ * @since 2023-06-13
+ */
+@Getter
+@Setter
+@TableName("lab_warning_config")
+@ApiModel(value = "WarningConfig对象", description = "预警配置表")
+public class WarningConfig extends Model<WarningConfig> {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("主键id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableId(value = "id", type = IdType.ASSIGN_ID)
+    private Long id;
+
+    @ApiModelProperty("预警类型(1算法识别 2化学品 3气瓶)")
+    private Integer warningType;
+
+    @ApiModelProperty("违规带离(1系统通知 2短信通知 3声光报警)")
+    private String illegalRemoval;
+
+    @ApiModelProperty("超时未归还(1系统通知 2短信通知 3声光报警)")
+    private String timeout;
+
+    @ApiModelProperty("已过期(1系统通知 2短信通知 3声光报警)")
+    private String expired;
+
+    @ApiModelProperty("即将过期(1系统通知 2短信通知 3声光报警)")
+    private String unexpired;
+
+    @ApiModelProperty("过期提醒数")
+    private Integer expiredWarnCount;
+
+    @ApiModelProperty("即将过期提醒天数")
+    private Integer unexpiredWarnDays;
+
+    @ApiModelProperty("穿戴检测周期")
+    private Integer wearDetectionCycle;
+
+    @ApiModelProperty("异常再识别率")
+    private Double anomalyRate;
+
+    @ApiModelProperty("异常再识别数")
+    private Integer anomalyCount;
+
+    @ApiModelProperty("系统通知")
+    private Integer systemNotice;
+
+    @ApiModelProperty("短信通知")
+    private Integer messageNotice;
+
+    @ApiModelProperty("语音播报通知")
+    private Integer voiceNotcie;
+
+    @ApiModelProperty("创建人名称")
+    private String createName;
+
+    @ApiModelProperty("创建人ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long createBy;
+
+    @ApiModelProperty("创建时间")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("修改人名称")
+    private String updateName;
+
+    @ApiModelProperty("修改人ID")
+    @TableField(fill = FieldFill.UPDATE)
+    private Long updateBy;
+
+    @ApiModelProperty("修改时间")
+    @TableField(fill = FieldFill.UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty("是否删除(0否 1是)")
+    private Boolean isDeleted;
+
+
+
+    @Override
+    public Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 86 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/WarningDetail.java

@@ -0,0 +1,86 @@
+package com.zd.laboratory.domain;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 预警详情表
+ * </p>
+ *
+ * @author hzw
+ * @since 2023-06-16
+ */
+@Data
+@TableName("lab_warning_detail")
+@ApiModel(value = "WarningDetail对象", description = "预警详情表")
+public class WarningDetail extends Model<WarningDetail> {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("主键id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableId(value = "id", type = IdType.ASSIGN_ID)
+    private Long id;
+
+    @ApiModelProperty("日志id")
+    private Long logId;
+
+    @ApiModelProperty("实验室id")
+    private Long subId;
+
+    @ApiModelProperty("摄像机编号")
+    private Long photoNum;
+
+    @ApiModelProperty("预警类型(1预案抓拍 2穿戴抓拍)")
+    private Integer type;
+
+    @ApiModelProperty("图片路径")
+    private String photoUrl;
+
+    @ApiModelProperty("回调图片路径")
+    private String callbackPhotoUrl;
+
+    @ApiModelProperty("识别结果(是否异常)")
+    private Boolean result;
+
+    @ApiModelProperty("创建人名称")
+    private String createName;
+
+    @ApiModelProperty("创建人ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long createBy;
+
+    @ApiModelProperty("创建时间")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("修改人名称")
+    private String updateName;
+
+    @ApiModelProperty("修改人ID")
+    @TableField(fill = FieldFill.UPDATE)
+    private Long updateBy;
+
+    @ApiModelProperty("修改时间")
+    @TableField(fill = FieldFill.UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty("是否删除(0否 1是)")
+    private Boolean isDeleted;
+
+
+    @Override
+    public Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 149 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/WarningNoticeLog.java

@@ -0,0 +1,149 @@
+package com.zd.laboratory.domain;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 预警通知日志
+ * </p>
+ *
+ * @author hzw
+ * @since 2023-06-13
+ */
+@Data
+@TableName("lab_warning_notice_log")
+@ApiModel(value = "WarningNoticeLog对象", description = "预警通知日志")
+public class WarningNoticeLog extends Model<WarningNoticeLog> {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("主键id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableId(value = "id", type = IdType.ASSIGN_ID)
+    private Long id;
+
+    @ApiModelProperty("keyId")
+    private Long keyId;
+
+    @ApiModelProperty("预警内容")
+    private String warningContent;
+
+    @ApiModelProperty("预警类型(1算法识别 2化学品 3气瓶 4预案)")
+    private Integer warningType;
+
+    @ApiModelProperty("预警下级类型(1违规带离,2超时未归还,3即将过期 4已过期)")
+    private Integer warningSubType;
+
+    @ApiModelProperty("预警方式(1系统通知 2短信通知 3声光报警)")
+    private String warningWay;
+
+    @ApiModelProperty("实验室id")
+    private Long subId;
+
+    @ApiModelProperty("实验室名称")
+    private String subName;
+
+    @ApiModelProperty("楼栋名称")
+    private String buildName;
+
+    @ApiModelProperty("楼层名称")
+    private String floorName;
+
+    @ApiModelProperty("房间号")
+    private String roomNum;
+
+    @ApiModelProperty("预警时间")
+    private LocalDateTime warningTime;
+
+    @ApiModelProperty("气体/化学品名称")
+    private String name;
+
+    @ApiModelProperty("余量")
+    private BigDecimal margin;
+
+    @ApiModelProperty("规格")
+    private String specification;
+
+    @ApiModelProperty("申领人")
+    private String apply;
+
+    @ApiModelProperty("申领时间")
+    private LocalDateTime applyTime;
+
+    @ApiModelProperty("存放位置")
+    private String deposit;
+
+    @ApiModelProperty("记录视频")
+    private String recordVideo;
+
+    @ApiModelProperty("记录照片")
+    private String recordPhoto;
+
+    @ApiModelProperty("持续时间")
+    private Integer riskDuration;
+
+    @ApiModelProperty("响应人员")
+    private String responder;
+
+    @ApiModelProperty("室内人员")
+    private String indoorUser;
+
+    @ApiModelProperty("预案开始时间")
+    private LocalDateTime startTime;
+
+    @ApiModelProperty("预案结束时间")
+    private LocalDateTime endTime;
+
+    @ApiModelProperty("入库时间")
+    private LocalDateTime entryTime;
+
+    @ApiModelProperty("过期时间")
+    private LocalDateTime expirationTime;
+
+    @ApiModelProperty("所有人")
+    private String holder;
+
+    @ApiModelProperty("是否语音播报(0否 1是)")
+    private Integer voiceBroadcast;
+
+    @ApiModelProperty("创建人名称")
+    private String createName;
+
+    @ApiModelProperty("创建人ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long createBy;
+
+    @ApiModelProperty("创建时间")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("修改人名称")
+    private String updateName;
+
+    @ApiModelProperty("修改人ID")
+    @TableField(fill = FieldFill.UPDATE)
+    private Long updateBy;
+
+    @ApiModelProperty("修改时间")
+    @TableField(fill = FieldFill.UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty("是否删除(0否 1是)")
+    private Boolean isDeleted;
+
+    @Override
+    public Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 14 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/dto/QueryAppWarningLogParam.java

@@ -0,0 +1,14 @@
+package com.zd.laboratory.domain.dto;
+
+import com.zd.model.page.PageQuery;
+import lombok.Data;
+
+/**
+ * @Description 查询小程序抱紧日志入参
+ * @Author hzw
+ * @Date 2023/6/21 14:02
+ * @Version 2.0
+ */
+@Data
+public class QueryAppWarningLogParam extends PageQuery {
+}

+ 29 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/dto/QueryWarningLogParam.java

@@ -0,0 +1,29 @@
+package com.zd.laboratory.domain.dto;
+
+import com.zd.model.page.PageQuery;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @Description 查询报警记录入参
+ * @Author hzw
+ * @Date 2023/6/13 14:31
+ * @Version 2.0
+ */
+@Data
+public class QueryWarningLogParam extends PageQuery {
+    @ApiModelProperty("预警类型(1算法识别 2化学品 3气瓶 4预案")
+    private Integer warningType;
+
+    @ApiModelProperty("预警方式(1系统通知 2短信通知 3声光报警)")
+    private String warningWay;
+
+    @ApiModelProperty("预警开始时间")
+    private LocalDateTime warningStartTime;
+
+    @ApiModelProperty("预警结束时间")
+    private LocalDateTime warningEndTime;
+
+}

+ 15 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/vo/BottleVO.java

@@ -0,0 +1,15 @@
+package com.zd.laboratory.domain.vo;
+
+import lombok.Data;
+
+/**
+ * @Description 气瓶信息VO
+ * @Author hzw
+ * @Date 2023/6/13 14:56
+ * @Version 2.0
+ */
+@Data
+public class BottleVO {
+
+
+}

+ 13 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/vo/ChemicalInfoVo.java

@@ -0,0 +1,13 @@
+package com.zd.laboratory.domain.vo;
+
+import lombok.Data;
+
+/**
+ * @Description 化学品信息VO
+ * @Author hzw
+ * @Date 2023/6/13 14:53
+ * @Version 2.0
+ */
+@Data
+public class ChemicalInfoVo {
+}

+ 22 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/vo/MessageVO.java

@@ -0,0 +1,22 @@
+package com.zd.laboratory.domain.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @Description 短信通知Vo
+ * @Author hzw
+ * @Date 2023/6/13 14:57
+ * @Version 2.0
+ */
+@Data
+public class MessageVO {
+    @ApiModelProperty("姓名(实验室负责人)")
+    private String name;
+
+    @ApiModelProperty("短信通知时间")
+    private String messageTime;
+
+    @ApiModelProperty("是否成功")
+    private String isSuccess;
+}

+ 117 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/domain/vo/WarningNoticeLogVO.java

@@ -0,0 +1,117 @@
+package com.zd.laboratory.domain.vo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.zd.laboratory.domain.WarningDetail;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * @Description 预警日志详情VO
+ * @Author hzw
+ * @Date 2023/6/13 14:49
+ * @Version 2.0
+ */
+@Data
+public class WarningNoticeLogVO {
+
+    @ApiModelProperty("主键id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableId(value = "id", type = IdType.ASSIGN_ID)
+    private Long id;
+
+    @ApiModelProperty("keyId")
+    private Long keyId;
+
+    @ApiModelProperty("预警内容")
+    private String warningContent;
+
+    @ApiModelProperty("预警类型(1算法识别 2化学品 3气瓶 4预案")
+    private Integer warningType;
+
+    @ApiModelProperty("预警下级类型(1违规带离,2超时未归还,3即将过期 4已过期)")
+    private Integer warningSubType;
+
+    @ApiModelProperty("预警方式(1系统通知 2短信通知 3声光报警)")
+    private String warningWay;
+
+    @ApiModelProperty("实验室id")
+    private Long subId;
+
+    @ApiModelProperty("实验室名称")
+    private String subName;
+
+    @ApiModelProperty("楼栋名称")
+    private String buildName;
+
+    @ApiModelProperty("楼层名称")
+    private String floorName;
+
+    @ApiModelProperty("房间号")
+    private String roomNum;
+
+    @ApiModelProperty("预警时间")
+    private LocalDateTime warningTime;
+
+    @ApiModelProperty("气体/化学品名称")
+    private String name;
+
+    @ApiModelProperty("余量")
+    private BigDecimal margin;
+
+    @ApiModelProperty("规格")
+    private String specification;
+    @ApiModelProperty("申领人")
+    private String apply;
+    @ApiModelProperty("申领时间")
+    private LocalDateTime applyTime;
+    @ApiModelProperty("存放位置")
+    private String deposit;
+    @ApiModelProperty("记录视频")
+    private String recordVideo;
+    @ApiModelProperty("记录照片")
+    private String recordPhoto;
+    @ApiModelProperty("持续时间")
+    private Integer riskDuration;
+    @ApiModelProperty("响应人员")
+    private String responder;
+    @ApiModelProperty("室内人员")
+    private String indoorUser;
+    @ApiModelProperty("预案开始时间")
+    private LocalDateTime startTime;
+    @ApiModelProperty("预案结束时间")
+    private LocalDateTime endTime;
+    @ApiModelProperty("入库时间")
+    private LocalDateTime entryTime;
+    @ApiModelProperty("过期时间")
+    private LocalDateTime expirationTime;
+    @ApiModelProperty("所有人")
+    private String holder;
+
+    @ApiModelProperty("是否语音播报(0否 1是)")
+    private Integer voiceBroadcast;
+    @ApiModelProperty("创建人名称")
+    private String createName;
+
+    @ApiModelProperty("创建人ID")
+    private Long createBy;
+
+    @ApiModelProperty("创建时间")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("创建时间年月日")
+    private LocalDate createDate;
+
+    @ApiModelProperty("告警详情信息")
+    private List<WarningDetail> warningDetailList;
+
+    @ApiModelProperty("短信通知")
+    private List<MessageVO> messageVOList;
+}

+ 224 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/event/RedisExpiredPhotographListener.java

@@ -0,0 +1,224 @@
+package com.zd.laboratory.event;
+
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.zd.algorithm.api.alarm.entity.AlarmEntrty;
+import com.zd.algorithm.api.alarm.entity.Routes;
+import com.zd.algorithm.api.alarm.entity.SendTypes;
+import com.zd.algorithm.api.alarm.feign.RemoteAlarmService;
+import com.zd.algorithm.api.forward.bo.AlgorithmWarningBo;
+import com.zd.algorithm.api.forward.feign.RemoteForwardService;
+import com.zd.algorithm.api.forward.vo.AlgorithmWarningVo;
+import com.zd.algorithm.api.speaker.entity.ParamVo;
+import com.zd.algorithm.api.speaker.entity.PlayVo;
+import com.zd.algorithm.api.speaker.feign.RemoteSpeakService;
+import com.zd.common.core.redis.RedisService;
+import com.zd.laboratory.api.dto.CheckSubjectDto;
+import com.zd.laboratory.api.dto.WarningNoticeLogDto;
+import com.zd.laboratory.api.entity.LabMessageContent;
+import com.zd.laboratory.domain.LabHardware;
+import com.zd.laboratory.domain.WarningConfig;
+import com.zd.laboratory.domain.WarningDetail;
+import com.zd.laboratory.domain.WarningNoticeLog;
+import com.zd.laboratory.service.*;
+import com.zd.model.constant.BaseConstants;
+import com.zd.model.constant.HttpStatus;
+import com.zd.model.domain.R;
+import com.zd.model.domain.ResultData;
+import com.zd.model.entity.SysFile;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.connection.Message;
+import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
+import org.springframework.data.redis.listener.RedisMessageListenerContainer;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * @Description redis过期抓拍监听类
+ * @Author hzw
+ * @Date 2023/6/16 13:38
+ * @Version 2.0
+ */
+@Slf4j
+@Component
+public class RedisExpiredPhotographListener extends KeyExpirationEventMessageListener {
+
+    @Autowired
+    private RedisService redisService;
+
+    @Resource
+    private RemoteForwardService remoteForwardService;
+
+    @Autowired
+    private ILabHardwareService labHardwareService;
+
+    @Autowired
+    private WarningDetailService warningDetailService;
+
+    @Autowired
+    private WarningNoticeLogService warningNoticeLogService;
+
+    @Autowired
+    private WarningConfigService warningConfigService;
+
+    @Autowired
+    private ILabSubjectService labSubjectService;
+
+    @Autowired
+    private ILabMessageContentService labMessageContentService;
+
+    @Resource
+    private RemoteAlarmService remoteAlarmService;
+
+    @Autowired
+    private RemoteSpeakService remoteSpeakService;
+
+    @Autowired
+    private ILabSparseHardwareService labSparseHardwareService;
+
+    /**
+     * Creates new {@link MessageListener} for {@code __keyevent@*__:expired} messages.
+     *
+     * @param listenerContainer must not be {@literal null}.
+     */
+    public RedisExpiredPhotographListener(RedisMessageListenerContainer listenerContainer) {
+        super(listenerContainer);
+    }
+
+    @Override
+    public void onMessage(Message message, byte[] bytes) {
+        String key = new String(message.getBody());
+        if (key.indexOf(BaseConstants.PHOTOGRAPH_QUEUE) != -1) {
+            log.info("预警异常,缓存信息:" + key);
+            String[] keyStr = key.split(BaseConstants.PHOTOGRAPH_QUEUE + "~");
+            WarningNoticeLog warningNoticeLog = JSON.parseObject(keyStr[1], WarningNoticeLog.class);
+            //调用拍摄照片接口
+            LabHardware labHardware = labHardwareService.findCameraByType(warningNoticeLog.getSubId(), 4, 1);
+            if (StringUtils.isNotBlank(labHardware.getIpAddress())) {
+                //拼装StreamUrl
+                String streamUrl = "rtsp://admin:hk123456@" + labHardware.getIpAddress() + ":554/h264/ch1/main/av_stream";
+                R<SysFile> fileR = remoteForwardService.photograph(streamUrl);
+                log.info("文件上传状态:{},接口返回消息:{},文件上传路径:{}", fileR.getCode(), fileR.getMsg(), fileR.getData());
+                //调用照片到算法服务,返回结果
+                AlgorithmWarningBo algorithmWarningBo = new AlgorithmWarningBo();
+                algorithmWarningBo.setId(warningNoticeLog.getId());
+                algorithmWarningBo.setSubId(warningNoticeLog.getSubId());
+                algorithmWarningBo.setSubName(warningNoticeLog.getSubName());
+                algorithmWarningBo.setFile(fileR.getData().getMultipartFile());
+                ResultData resultData = remoteForwardService.warningCheck(algorithmWarningBo);
+                if (HttpStatus.SUCCESS == resultData.getCode()) {
+                    resultData.getData();
+                    AlgorithmWarningVo algorithmWarningVo = JSON.parseObject(JSONObject.toJSONString(resultData), AlgorithmWarningVo.class);
+                    WarningDetail warningDetail = new WarningDetail();
+                    warningDetail.setLogId(warningNoticeLog.getId());
+                    warningDetail.setSubId(warningNoticeLog.getSubId());
+                    //预警类型(1预案抓拍 2穿戴抓拍)
+                    //warningDetail.setType();
+                    warningDetail.setPhotoUrl(fileR.getData().getUrl());
+                    warningDetail.setCallbackPhotoUrl(algorithmWarningVo.getResultImage());
+                    warningDetail.setResult(algorithmWarningVo.getIsAlert());
+                    warningDetail.setCreateTime(LocalDateTime.now());
+                    warningDetailService.save(warningDetail);
+                }
+
+                if (!redisService.hasKey(key)) {
+                    //如果没有这个key了 则统计异常率
+                    //查询配置
+                    long count1 = warningNoticeLogService.count(new LambdaQueryWrapper<WarningNoticeLog>().eq(WarningNoticeLog::getSubId, warningNoticeLog.getSubId()));
+                    WarningConfig warningConfig = warningConfigService.getOne(new LambdaQueryWrapper<WarningConfig>().eq(WarningConfig::getWarningType, 1));
+                    List<WarningDetail> list = warningDetailService.list(new LambdaQueryWrapper<WarningDetail>().eq(WarningDetail::getLogId, warningNoticeLog.getId()));
+                    if (list.size() > 0) {
+                        List<WarningDetail> collect = list.stream().filter(i -> i.getResult() == true).collect(Collectors.toList());
+                        double div = NumberUtil.div(collect.size(), warningConfig.getAnomalyCount().intValue());
+                        if (div > warningConfig.getAnomalyRate()) {
+
+                            WarningNoticeLogDto warningNoticeLogDto = new WarningNoticeLogDto();
+                            warningNoticeLogDto.setWarningType(1);
+                            warningNoticeLogDto.setWarningContent("未穿戴实验服");
+                            warningNoticeLogDto.setWarningTime(LocalDateTime.now());
+                            warningNoticeLogDto.setWarningWay(warningConfig.getIllegalRemoval());
+                            //查询到实验室负责人id 安全责任人id
+                            List<CheckSubjectDto> subjectInfoList = labSubjectService.findSubjectInfoList(String.valueOf(warningNoticeLog.getSubId()));
+                            StringBuffer userIds = new StringBuffer();
+                            StringBuffer phones = new StringBuffer();
+                            if (subjectInfoList.size() > 0) {
+                                CheckSubjectDto i = subjectInfoList.get(0);
+                                warningNoticeLogDto.setSubId(i.getSubId());
+                                warningNoticeLogDto.setSubName(i.getSubjectName());
+                                warningNoticeLogDto.setBuildName(i.getBuildName());
+                                warningNoticeLogDto.setFloorName(i.getFloorName());
+                                warningNoticeLogDto.setRoomNum(i.getRoomNumber());
+                                userIds.append(i.getSafeUserId()).append(",").append(i.getAdminId());
+                                phones.append(i.getAdminPhone()).append(",").append(i.getSafeUserPhone());
+                            }
+                            String text = "【实验室安全系统】实验室名称-监测到实验人员违规未穿戴实验服,请尽快确认。点击查看:http://";
+                            //系统 短信 语音通知
+                            if (warningConfig.getSystemNotice() != null && count1 > warningConfig.getSystemNotice()) {
+                                //系统通知
+                                LabMessageContent labMessageContent = new LabMessageContent();
+                                labMessageContent.setSendMode(2);
+                                labMessageContent.setSendRange(3);
+                                labMessageContent.setMessClass(1);
+                                labMessageContent.setMessType(13);
+                                labMessageContent.setSubIds(String.valueOf(warningNoticeLog.getSubId()));
+                                labMessageContent.setUserIds(userIds.toString());
+                                labMessageContent.setContent(text);
+                                labMessageContentService.sendMessage(labMessageContent);
+                            }
+                            if (warningConfig.getMessageNotice() != null && count1 > warningConfig.getMessageNotice()) {
+                                //短信通知
+                                String[] strings = Stream.of(phones.toString().split(",")).filter(a -> StrUtil.isNotBlank(a)).collect(Collectors.joining(",")).split(",");
+
+                                if (strings != null) {
+                                    AlarmEntrty alarmEntrty = new AlarmEntrty(Routes.NoticePush, strings, SendTypes.SMS.toString(), text);
+                                    remoteAlarmService.send(alarmEntrty);
+                                    log.info("气瓶发送短信打电话消息推送完成!");
+                                }
+                            }
+                            if (warningConfig.getVoiceNotcie() != null && count1 > warningConfig.getVoiceNotcie()) {
+                                //短信通知
+                                log.info("打开喇叭-远程调用查询喇叭列表,实验室id={}", warningNoticeLog.getSubId());
+                                Integer count = labSparseHardwareService.selectSpeakerCount();
+                                R deviceList = remoteSpeakService.getDeviceList(1, count + 10, -99L, warningNoticeLog.getSubId());
+                                log.info("打开喇叭-远程调用喇叭列表返回内容: deviceList={}", JSON.toJSONString(deviceList));
+                                if (deviceList.getCode() == 200) {
+                                    List<PlayVo> playVoList = new ArrayList<>();
+                                    List<Map<String, Object>> mapList = (List<Map<String, Object>>) deviceList.getData();
+                                    for (Map<String, Object> map : mapList) {
+                                        if (com.zd.common.core.utils.StringUtils.isNotNull(map.get("deviceSn")) && com.zd.common.core.utils.StringUtils.isNotNull(map.get("port"))) {
+                                            PlayVo playVo = new PlayVo();
+                                            playVo.setSn(map.get("deviceSn") + "");
+                                            playVo.setDeviceIp(map.get("deviceIp") + "");
+                                            playVo.setPort(Integer.parseInt(map.get("port") + ""));
+                                            ParamVo paramVo = new ParamVo();
+                                            paramVo.setVol(Integer.parseInt(map.get("deviceVol").toString()));
+                                            playVo.setParams(paramVo);
+                                            playVoList.add(playVo);
+                                        } else {
+                                            log.info("打开喇叭-喇叭deviceSn/port为空!");
+                                        }
+                                    }
+                                    log.info("打开喇叭-远程调用喇叭播放音乐,playVoList={}", JSON.toJSONString(playVoList));
+                                    R r = remoteSpeakService.textParseUrlIps("sss", playVoList);
+                                    log.info("打开喇叭-远程调用喇叭播放音乐返回信息:{}", JSON.toJSONString(r));
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

+ 2 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/mapper/AlarmLogMapper.java

@@ -61,4 +61,6 @@ public interface AlarmLogMapper {
     public int deleteAlarmLogByIds(Long[] ids);
 
     List<AlarmLog> selectNoBackAlarmLogList(Map<String, Object> params);
+
+    List<AlarmLog> selectAlarmLogByKeyId(Long keyId);
 }

+ 7 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/mapper/LabHardwareMapper.java

@@ -172,4 +172,11 @@ public interface LabHardwareMapper {
     String querySubNameById(Long hardId);
 
     String selectLabHardwareCameraBySubId(Long subId);
+
+    /**
+     * 根据类型查询摄像头信息
+     * @Param [subId, type, pcType]
+     * @Return com.zd.laboratory.domain.LabHardware
+     **/
+    LabHardware findCameraByType(@Param("subId") Long subId, @Param("type") Integer type, @Param("pcType") Integer pcType);
 }

+ 18 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/mapper/WarningConfigMapper.java

@@ -0,0 +1,18 @@
+package com.zd.laboratory.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zd.laboratory.domain.WarningConfig;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 预警配置表 Mapper 接口
+ * </p>
+ *
+ * @author hzw
+ * @since 2023-06-13
+ */
+@Mapper
+public interface WarningConfigMapper extends BaseMapper<WarningConfig> {
+
+}

+ 18 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/mapper/WarningDetailMapper.java

@@ -0,0 +1,18 @@
+package com.zd.laboratory.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zd.laboratory.domain.WarningDetail;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 预警详情表 Mapper 接口
+ * </p>
+ *
+ * @author hzw
+ * @since 2023-06-16
+ */
+@Mapper
+public interface WarningDetailMapper extends BaseMapper<WarningDetail> {
+
+}

+ 18 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/mapper/WarningNoticeLogMapper.java

@@ -0,0 +1,18 @@
+package com.zd.laboratory.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zd.laboratory.domain.WarningNoticeLog;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 预警通知日志 Mapper 接口
+ * </p>
+ *
+ * @author hzw
+ * @since 2023-06-13
+ */
+@Mapper
+public interface WarningNoticeLogMapper extends BaseMapper<WarningNoticeLog> {
+
+}

+ 7 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/IAlarmLogService.java

@@ -61,4 +61,11 @@ public interface IAlarmLogService {
     public int deleteAlarmLogById(Long id);
 
     List<AlarmLog> selectNoBackAlarmLogList(Map<String, Object> params);
+
+    /**
+     * 根据keyId查询报警日志
+     * @param keyId
+     * @return
+     */
+    List<AlarmLog> selectAlarmLogByKeyId(Long keyId);
 }

+ 9 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/ILabHardwareService.java

@@ -180,4 +180,13 @@ public interface ILabHardwareService {
      * @return
      */
     String selectLabHardwareCameraBySubId(Long subId);
+
+    /**
+     * 根据类型查询摄像头信息
+     * @Param [subId 实验室id,
+     *          type 设备类型(0,一体机 1,电源开关 2 智能通风,3,语音对讲,4,视频监控5,智能终端 6,智能门锁 ,7,RFID识别器,8,智能报警器,9,智能柜锁,11 海康门禁),
+     *          pcType 摄像头类型:(0普通摄像头 1抓拍摄像头 2违规带离摄像头)]
+     * @Return com.zd.laboratory.domain.LabHardware
+     **/
+    LabHardware findCameraByType(Long subId, Integer type, Integer pcType);
 }

+ 16 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/WarningConfigService.java

@@ -0,0 +1,16 @@
+package com.zd.laboratory.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zd.laboratory.domain.WarningConfig;
+
+/**
+ * <p>
+ * 预警配置表 服务类
+ * </p>
+ *
+ * @author hzw
+ * @since 2023-06-13
+ */
+public interface WarningConfigService extends IService<WarningConfig> {
+
+}

+ 16 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/WarningDetailService.java

@@ -0,0 +1,16 @@
+package com.zd.laboratory.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zd.laboratory.domain.WarningDetail;
+
+/**
+ * <p>
+ * 预警详情表 服务类
+ * </p>
+ *
+ * @author hzw
+ * @since 2023-06-16
+ */
+public interface WarningDetailService extends IService<WarningDetail> {
+
+}

+ 31 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/WarningNoticeLogService.java

@@ -0,0 +1,31 @@
+package com.zd.laboratory.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zd.laboratory.domain.WarningNoticeLog;
+import com.zd.laboratory.domain.vo.WarningNoticeLogVO;
+
+/**
+ * <p>
+ * 预警通知日志 服务类
+ * </p>
+ *
+ * @author hzw
+ * @since 2023-06-13
+ */
+public interface WarningNoticeLogService extends IService<WarningNoticeLog> {
+
+    /**
+     * 新增报警记录日志
+     * @Param [warningNoticeLog]
+     * @Return java.lang.Integer
+     **/
+    Long addWarningNoticeLog(WarningNoticeLog warningNoticeLog);
+
+    /**
+     * 根据id查询报警记录日志详情
+     * @Param [id]
+     * @Return com.zd.laboratory.domain.vo.WarningNoticeLogVO
+     **/
+    WarningNoticeLogVO getLogById(Long id);
+
+}

+ 5 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/AlarmLogServiceImpl.java

@@ -89,4 +89,9 @@ public class AlarmLogServiceImpl implements IAlarmLogService {
     public List<AlarmLog> selectNoBackAlarmLogList(Map<String, Object> params) {
         return alarmLogMapper.selectNoBackAlarmLogList(params);
     }
+
+    @Override
+    public List<AlarmLog> selectAlarmLogByKeyId(Long keyId) {
+        return alarmLogMapper.selectAlarmLogByKeyId(keyId);
+    }
 }

+ 5 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/LabHardwareServiceImpl.java

@@ -852,4 +852,9 @@ public class LabHardwareServiceImpl implements ILabHardwareService {
     public String selectLabHardwareCameraBySubId(Long subId) {
         return labHardwareMapper.selectLabHardwareCameraBySubId(subId);
     }
+
+    @Override
+    public LabHardware findCameraByType(Long subId, Integer type, Integer pcType) {
+        return labHardwareMapper.findCameraByType(subId,type,pcType);
+    }
 }

+ 79 - 4
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/LabMessageContentServiceImpl.java

@@ -16,8 +16,10 @@ import com.zd.laboratory.api.entity.LabMessageContent;
 import com.zd.laboratory.api.entity.SubAddrr;
 import com.zd.laboratory.domain.LabRiskPlanLevel;
 import com.zd.laboratory.domain.LabSubject;
+import com.zd.laboratory.domain.WarningNoticeLog;
 import com.zd.laboratory.domain.dto.LabMessageContentDTO;
 import com.zd.laboratory.domain.dto.LabMessageContentListQuery;
+import com.zd.algorithm.api.alarm.domain.UserPhoneInfo;
 import com.zd.laboratory.domain.vo.LabMessageContentVO;
 import com.zd.laboratory.domain.vo.LabSubjectAccessRecordVo;
 import com.zd.laboratory.domain.vo.LabSubjectVO;
@@ -28,13 +30,16 @@ import com.zd.laboratory.mqtt.entiy.MessageBody;
 import com.zd.laboratory.mqtt.enums.SendMode;
 import com.zd.laboratory.mqtt.service.impl.CommonSend;
 import com.zd.laboratory.service.*;
+import com.zd.model.constant.HttpStatus;
 import com.zd.model.constant.MqttConstants;
 import com.zd.model.domain.R;
 import com.zd.model.domain.per.PerPrefix;
+import com.zd.model.entity.SysUser;
 import com.zd.model.enums.WarnUserAttrEnum;
 import com.zd.system.api.feign.RemoteUserService;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
@@ -44,10 +49,7 @@ import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
+import java.util.*;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -88,6 +90,9 @@ public class LabMessageContentServiceImpl implements ILabMessageContentService {
     @Autowired
     private LabContentMachineMsgMapper labContentMachineMsgMapper;
 
+    @Autowired
+    private WarningNoticeLogService warningNoticeLogService;
+
     public Integer phoneMode;
 
     @Value("${phoneMode:0}")
@@ -241,6 +246,8 @@ public class LabMessageContentServiceImpl implements ILabMessageContentService {
             e.printStackTrace();
             logger.error("获取实验室内部短信发送人出错");
         }
+        //获取人员电话信息
+        List<UserPhoneInfo> userPhoneInfoList = getUserPhoneInfos(subject, phone);
         String[] strings = Stream.of(new String[]{subject.getAdminPhone(), subject.getSafeUserPhone(), phone})
                 .filter(a -> StrUtil.isNotBlank(a))
                 .collect(Collectors.joining(","))
@@ -259,10 +266,36 @@ public class LabMessageContentServiceImpl implements ILabMessageContentService {
                 }else if(alarms.contains(smsType)) {
                     alarmEntrty = new AlarmEntrty(Routes.NoticePush, strings, SendTypes.SMS.toString(),format);
                 }
+                alarmEntrty.setUserPhoneInfo(userPhoneInfoList);
                 MessageBody messageBody = new MessageBody();
                 messageBody.setData(alarmEntrty);
+                messageBody.setMessageId(groupId);
                 commonSend.send(MqttConstants.TOPIC_ALERT + labRiskPlanLevel.getRiskPlanId() + "/" + subject.getId(), messageBody, SendMode.DISTINCT);
                 logger.info("发送短信打电话消息推送完成!topic={},msg={}",MqttConstants.TOPIC_ALERT + labRiskPlanLevel.getRiskPlanId() + "/" + subject.getId(),JSON.toJSONString(messageBody));
+                WarningNoticeLog warningNoticeLog = new WarningNoticeLog();
+                warningNoticeLog.setKeyId(groupId);
+                warningNoticeLog.setSubName(subject.getName());
+                warningNoticeLog.setBuildName(subject.getDeptName());
+                warningNoticeLog.setFloorName(subject.getFloorName());
+                warningNoticeLog.setRoomNum(subject.getRoom());
+                warningNoticeLog.setWarningType(4);
+                //TODO 语音播报通知
+                warningNoticeLog.setVoiceBroadcast(1);
+                String riskPlanName = "";
+                if(labRiskPlanLevel.getRiskPlanLevel() ==1 ){
+                    riskPlanName = "低风险";
+                }
+                if(labRiskPlanLevel.getRiskPlanLevel() ==2 ){
+                    riskPlanName = "中风险";
+                }
+                if(labRiskPlanLevel.getRiskPlanLevel() ==3 ){
+                    riskPlanName = "较高风险";
+                }
+                if(labRiskPlanLevel.getRiskPlanLevel() ==4 ){
+                    riskPlanName = "高风险";
+                }
+                warningNoticeLog.setWarningContent(labRiskPlanLevel.getDescribe()+"-"+riskPlanName);
+                warningNoticeLogService.addWarningNoticeLog(warningNoticeLog);
                 try {
                     if (subject.getAdminId() != null) {
                         //发送预案消息(预案指挥中心) 没什么卵用 lab_warn_push_message
@@ -298,6 +331,48 @@ public class LabMessageContentServiceImpl implements ILabMessageContentService {
 
     }
 
+    @NotNull
+    private List<UserPhoneInfo> getUserPhoneInfos(LabSubjectVO subject, String phone) {
+        List<UserPhoneInfo> userPhoneInfoList = new ArrayList<>();
+        R<SysUser> sysUserR = remoteUserService.getUserByPhone(subject.getAdminPhone());
+        if (HttpStatus.SUCCESS != sysUserR.getCode()) {
+            logger.error("手机号码为:{}用户不存在!", phone);
+        }
+        UserPhoneInfo userPhoneInfo = new UserPhoneInfo();
+        userPhoneInfo.setPhone(subject.getAdminPhone());
+        userPhoneInfo.setNickName(sysUserR.getData().getNickName());
+        userPhoneInfo.setRole("实验室负责人");
+        userPhoneInfoList.add(userPhoneInfo);
+        String[] split = subject.getSafeUserPhone().split(",");
+        if(split != null && split.length >0){
+            for (String phoneNumber : split) {
+                R<SysUser> result = remoteUserService.getUserByPhone(phoneNumber);
+                if (HttpStatus.SUCCESS != result.getCode()) {
+                    logger.error("手机号码为:{}用户不存在!",phoneNumber);
+                }
+                UserPhoneInfo userPhoneInfo1 = new UserPhoneInfo();
+                userPhoneInfo1.setPhone(phoneNumber);
+                userPhoneInfo1.setNickName(result.getData().getNickName());
+                userPhoneInfo1.setRole("安全责任人");
+                userPhoneInfoList.add(userPhoneInfo1);
+            }
+        }
+        if(StringUtils.isNotBlank(phone)){
+            for (String phoneNumber : phone.split(",")) {
+                R<SysUser> result1 = remoteUserService.getUserByPhone(phoneNumber);
+                if (HttpStatus.SUCCESS != result1.getCode()) {
+                    logger.error("手机号码为:{}用户不存在!",phoneNumber);
+                }
+                UserPhoneInfo userPhoneInfo2 = new UserPhoneInfo();
+                userPhoneInfo2.setPhone(phoneNumber);
+                userPhoneInfo2.setNickName(result1.getData().getNickName());
+                userPhoneInfo2.setRole("室内人员");
+                userPhoneInfoList.add(userPhoneInfo2);
+            }
+        }
+        return userPhoneInfoList;
+    }
+
     private String getDoingUserId(LabSubjectVO subject) {
         LabSubjectAccessRecordVo labSubjectAccessRecordVo;
         labSubjectAccessRecordVo = new LabSubjectAccessRecordVo();

+ 11 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/LabRiskPlanAbnormalDescServiceImpl.java

@@ -1,14 +1,18 @@
 package com.zd.laboratory.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.zd.common.core.exception.ServiceException;
 import com.zd.common.core.utils.StringUtils;
 import com.zd.laboratory.domain.LabRiskPlanAbnormalDesc;
+import com.zd.laboratory.domain.WarningNoticeLog;
 import com.zd.laboratory.mapper.LabHardwareStateMapper;
 import com.zd.laboratory.mapper.LabRiskPlanAbnormalDescMapper;
 import com.zd.laboratory.service.ILabRiskPlanAbnormalDescService;
+import com.zd.laboratory.service.WarningNoticeLogService;
 import com.zd.model.entity.SysUser;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -31,6 +35,9 @@ public class LabRiskPlanAbnormalDescServiceImpl implements ILabRiskPlanAbnormalD
     @Autowired
     private LabHardwareStateMapper hardwareStateMapper;
 
+    @Autowired
+    private WarningNoticeLogService warningNoticeLogService;
+
     @Override
     public int insert(LabRiskPlanAbnormalDesc labRiskPlanAbnormalDesc) {
         if (labRiskPlanAbnormalDesc != null) {
@@ -115,6 +122,10 @@ public class LabRiskPlanAbnormalDescServiceImpl implements ILabRiskPlanAbnormalD
             desc.setHandledPerson(handledPerson);
             desc.setRecordVideo(recordVideo);
             desc.setUpdateTime(new Date());
+            warningNoticeLogService.update(new LambdaUpdateWrapper<WarningNoticeLog>().eq(WarningNoticeLog::getKeyId,groupId)
+                    .set(WarningNoticeLog::getRiskDuration,rd).set(WarningNoticeLog::getRecordVideo,recordVideo)
+                    .set(WarningNoticeLog::getResponder,handledPerson).set(WarningNoticeLog::getStartTime,desc.getStartDate())
+                    .set(WarningNoticeLog::getEndTime,now).set(WarningNoticeLog::getWarningContent,desc.getRiskReason()));
             return labRiskPlanAbnormalDescMapper.updateByGroupId(desc);
         }
         return 0;

+ 1 - 1
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/LabRiskPlanServiceImpl.java

@@ -1281,7 +1281,7 @@ public class LabRiskPlanServiceImpl extends ServiceImpl<LabRiskPlanMapper, LabRi
         labWarnPushMessage.setRiskGroup(groupId);
         String string = StringUtils.isBlank(labRiskPlanLevel.getInformation()) ? "" : labRiskPlanLevel.getInformation();
         labWarnPushMessage.setContext(RiskPlanConstants.LAB_SAFETY_MANAGEMENT_SYSTEM + labRiskPlanLevel.getContent() + string);
-        labWarnPushMessage.setPushType(WarnMessageTypeEnum.voice);
+        labWarnPushMessage.setPushType(WarnMessageTypeEnum.voice.getCode());
         labWarnPushMessage.setWarnId(labRiskPlanLevel.getRiskPlanId());
         labWarnPushMessage.setSubId(subjectId);
         labWarnPushMessage.setCreateTime(new Date());

+ 1 - 1
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/LabWarnPushMessageServiceImpl.java

@@ -83,7 +83,7 @@ public class LabWarnPushMessageServiceImpl implements ILabWarnPushMessageService
                 labWarnPushMessage.setRiskGroup(groupId);
                 String str= StringUtils.isBlank(labRiskPlanLevel.getMessage()) ? "" : labRiskPlanLevel.getMessage();
                 labWarnPushMessage.setContext(RiskPlanConstants.LAB_SAFETY_MANAGEMENT_SYSTEM + labRiskPlanLevel.getContent() + str);
-                labWarnPushMessage.setPushType(WarnMessageTypeEnum.SMS);
+                labWarnPushMessage.setPushType(WarnMessageTypeEnum.SMS.getCode());
                 labWarnPushMessage.setWarnId(labRiskPlanLevel.getRiskPlanId());
                 labWarnPushMessage.setSubId(subId);
                 labWarnPushMessage.setCreateTime(new Date());

+ 20 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/WarningConfigServiceImpl.java

@@ -0,0 +1,20 @@
+package com.zd.laboratory.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zd.laboratory.domain.WarningConfig;
+import com.zd.laboratory.mapper.WarningConfigMapper;
+import com.zd.laboratory.service.WarningConfigService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 预警配置表 服务实现类
+ * </p>
+ *
+ * @author hzw
+ * @since 2023-06-13
+ */
+@Service
+public class WarningConfigServiceImpl extends ServiceImpl<WarningConfigMapper, WarningConfig> implements WarningConfigService {
+
+}

+ 20 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/WarningDetailServiceImpl.java

@@ -0,0 +1,20 @@
+package com.zd.laboratory.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zd.laboratory.domain.WarningDetail;
+import com.zd.laboratory.mapper.WarningDetailMapper;
+import com.zd.laboratory.service.WarningDetailService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 预警详情表 服务实现类
+ * </p>
+ *
+ * @author hzw
+ * @since 2023-06-16
+ */
+@Service
+public class WarningDetailServiceImpl extends ServiceImpl<WarningDetailMapper, WarningDetail> implements WarningDetailService {
+
+}

+ 115 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/service/impl/WarningNoticeLogServiceImpl.java

@@ -0,0 +1,115 @@
+package com.zd.laboratory.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zd.algorithm.api.alarm.entity.AlarmLog;
+import com.zd.common.core.redis.RedisService;
+import com.zd.common.core.utils.BeanUtils;
+import com.zd.laboratory.domain.WarningConfig;
+import com.zd.laboratory.domain.WarningDetail;
+import com.zd.laboratory.domain.WarningNoticeLog;
+import com.zd.laboratory.domain.vo.LabOnlineSubVO;
+import com.zd.laboratory.domain.vo.LabSubjectVO;
+import com.zd.laboratory.domain.vo.MessageVO;
+import com.zd.laboratory.domain.vo.WarningNoticeLogVO;
+import com.zd.laboratory.mapper.LabHardwareStateMapper;
+import com.zd.laboratory.mapper.WarningNoticeLogMapper;
+import com.zd.laboratory.service.IAlarmLogService;
+import com.zd.laboratory.service.WarningConfigService;
+import com.zd.laboratory.service.WarningDetailService;
+import com.zd.laboratory.service.WarningNoticeLogService;
+import com.zd.model.constant.BaseConstants;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * <p>
+ * 预警通知日志 服务实现类
+ * </p>
+ *
+ * @author hzw
+ * @since 2023-06-13
+ */
+@Service
+@Slf4j
+public class WarningNoticeLogServiceImpl extends ServiceImpl<WarningNoticeLogMapper, WarningNoticeLog> implements WarningNoticeLogService {
+
+    @Autowired
+    private LabHardwareStateMapper hardwareStateMapper;
+    @Autowired
+    private WarningConfigService warningConfigService;
+    @Autowired
+    private RedisService redisService;
+    @Autowired
+    private WarningDetailService warningDetailService;
+    @Autowired
+    private IAlarmLogService alarmLogService;
+
+    @Override
+    public Long addWarningNoticeLog(WarningNoticeLog warningNoticeLog) {
+        warningNoticeLog.setCreateTime(LocalDateTime.now());
+        int insert = baseMapper.insert(warningNoticeLog);
+        if (insert > 0) {
+            return warningNoticeLog.getId();
+        }
+        return 0L;
+    }
+
+    @Override
+    public WarningNoticeLogVO getLogById(Long id) {
+        WarningNoticeLogVO warningNoticeLogVO = new WarningNoticeLogVO();
+        WarningNoticeLog warningNoticeLog = baseMapper.selectById(id);
+        BeanUtils.copyProperties(warningNoticeLog, warningNoticeLogVO);
+        //todo 查询短信、电话等信息
+        List<WarningDetail> list = warningDetailService.list(new LambdaQueryWrapper<WarningDetail>().eq(WarningDetail::getLogId, warningNoticeLogVO.getId()).orderByDesc(WarningDetail::getId));
+        warningNoticeLogVO.setWarningDetailList(list);
+        List<AlarmLog> alarmLogs = alarmLogService.selectAlarmLogByKeyId(warningNoticeLog.getKeyId());
+        List<MessageVO> messageVOList = new ArrayList<>();
+        Optional.ofNullable(alarmLogs).orElseGet(Collections::emptyList).forEach(alarmLog -> {
+            MessageVO messageVO = new MessageVO();
+            messageVO.setName(alarmLog.getNickName()+"("+alarmLog.getRole()+")");
+            messageVO.setMessageTime(alarmLog.getCreateTime().toString());
+            messageVO.setIsSuccess(alarmLog.getStatus());
+            messageVOList.add(messageVO);
+        });
+        warningNoticeLogVO.setMessageVOList(messageVOList);
+        return warningNoticeLogVO;
+    }
+
+    /**
+     * 实验室有人时定时拍摄识别实验服
+     */
+    @Scheduled(cron = "0 0/30 * * * ? ")
+    public void labCoatTask() {
+        //查询实验室是否有人
+        List<LabOnlineSubVO> labSubjects = hardwareStateMapper.onlineByBigView(new LabSubjectVO());
+        //查询配置
+        WarningConfig warningConfig = warningConfigService.getOne(new LambdaQueryWrapper<WarningConfig>().eq(WarningConfig::getWarningType, 2));
+        Optional.ofNullable(labSubjects).orElseGet(Collections::emptyList).stream().forEach(LabOnlineSubVO -> {
+            //异常识别频率
+            Long frequency = 60L;
+            //异常再识别数
+            Integer anomalyCount = warningConfig.getAnomalyCount();
+            WarningNoticeLog warningNoticeLog = new WarningNoticeLog();
+            warningNoticeLog.setWarningType(1);
+            warningNoticeLog.setSubId(LabOnlineSubVO.getId());
+            warningNoticeLog.setSubName(LabOnlineSubVO.getName());
+            baseMapper.insert(warningNoticeLog);
+            for (int i = 0; i < anomalyCount; i++) {
+                JSONObject jsonObject = new JSONObject();
+                jsonObject.put(BaseConstants.PHOTOGRAPH_QUEUE,warningNoticeLog);
+                redisService.setCacheObject(BaseConstants.PHOTOGRAPH_QUEUE+"~"+ jsonObject,jsonObject, frequency * i, TimeUnit.SECONDS);
+            }
+        });
+    }
+}

+ 8 - 2
zd-modules/zd-modules-laboratory/src/main/resources/bootstrap.yml

@@ -16,9 +16,15 @@ mybatis:
 #    log-impl: com.zd.common.core.utils.MySlf4jImpl #开启sql打印到info
     # Mybatis开启驼峰映射
     mapUnderscoreToCamelCase: true
-mybatis-plus:
-  type-handlers-package: com.zd.model.enums
+#mybatis-plus:
+#  type-handlers-package: com.zd.model.enums
 #  configuration:
 #    #log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启sql日志到控制台
 #    log-impl: com.zd.common.core.utils.MySlf4jImpl
 
+# mybatis配置
+mybatis-plus:
+  configuration:
+    cache-enabled: false
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+

+ 7 - 0
zd-modules/zd-modules-laboratory/src/main/resources/mapper/laboratory/AlarmLogMapper.xml

@@ -6,6 +6,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <resultMap type="com.zd.algorithm.api.alarm.entity.AlarmLog" id="AlarmLogResult">
         <result property="id" column="id"/>
+        <result property="keyId" column="key_id"/>
         <result property="createTime" column="create_time"/>
         <result property="updateTime" column="update_time"/>
         <result property="phone" column="phone"/>
@@ -13,6 +14,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="notice" column="notice"/>
         <result property="method" column="method"/>
         <result property="isBack" column="is_back"/>
+        <result property="nickName" column="nick_name"/>
+        <result property="role" column="role"/>
     </resultMap>
 
     <sql id="selectAlarmLogVo">
@@ -59,6 +62,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         where is_back &lt; #{retryCount} and status = "失败"
         having TIMESTAMPDIFF(minute,create_time,#{date}) &lt; 30
     </select>
+    <select id="selectAlarmLogByKeyId" resultType="com.zd.algorithm.api.alarm.entity.AlarmLog">
+        <include refid="selectAlarmLogVo"/>
+        where key_id = #{keyId}
+    </select>
 
     <insert id="insertAlarmLog" parameterType="com.zd.algorithm.api.alarm.entity.AlarmLog" useGeneratedKeys="true" keyProperty="id">
         insert into alarm_log

+ 9 - 0
zd-modules/zd-modules-laboratory/src/main/resources/mapper/laboratory/LabHardwareMapper.xml

@@ -594,4 +594,13 @@
     <select id="selectLabHardwareCameraBySubId" resultType="java.lang.String">
         SELECT GROUP_CONCAT(lh.hardware_num) FROM lab_hardware lh where lh.subject_id = #{subId} and lh.type = 4 and lh.device_status=1
     </select>
+
+    <select id="findCameraByType" resultMap="LabHardwareResult">
+        SELECT lh.*
+        FROM lab_hardware lh
+        where lh.ip_address is not null
+        and lh.subject_id = #{subId}
+        and lh.type = #{type}
+        and lh.pc_type = #{pcType}
+    </select>
 </mapper>

+ 36 - 0
zd-modules/zd-modules-laboratory/src/main/resources/mapper/laboratory/WarningConfigMapper.xml

@@ -0,0 +1,36 @@
+<?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.zd.laboratory.mapper.WarningConfigMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.zd.laboratory.domain.WarningConfig">
+        <id column="id" property="id" />
+        <result column="warning_type" property="warningType" />
+        <result column="illegal_removal" property="illegalRemoval" />
+        <result column="timeout" property="timeout" />
+        <result column="expired" property="expired" />
+        <result column="unexpired" property="unexpired" />
+        <result column="expired_warn_count" property="expiredWarnCount" />
+        <result column="unexpired_warn_days" property="unexpiredWarnDays" />
+        <result column="wear_detection_cycle" property="wearDetectionCycle" />
+        <result column="anomaly_rate" property="anomalyRate" />
+        <result column="anomaly_count" property="anomalyCount" />
+        <result column="system_notice" property="systemNotice" />
+        <result column="message_notice" property="messageNotice" />
+        <result column="voice_notcie" property="voiceNotcie" />
+        <result column="create_name" property="createName" />
+        <result column="create_by" property="createBy" />
+        <result column="create_time" property="createTime" />
+        <result column="update_name" property="updateName" />
+        <result column="update_by" property="updateBy" />
+        <result column="update_time" property="updateTime" />
+        <result column="is_deleted" property="isDeleted" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, warning_type, illegal_removal, timeout, expired, unexpired, expired_warn_count, unexpired_warn_days, wear_detection_cycle, anomaly_rate, anomaly_count, system_notice, message_notice, voice_notcie, create_name, create_by, create_time, update_name, update_by, update_time, is_deleted
+    </sql>
+
+
+</mapper>

+ 29 - 0
zd-modules/zd-modules-laboratory/src/main/resources/mapper/laboratory/WarningDetailMapper.xml

@@ -0,0 +1,29 @@
+<?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.zd.laboratory.mapper.WarningDetailMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.zd.laboratory.domain.WarningDetail">
+        <id column="id" property="id" />
+        <result column="log_id" property="logId" />
+        <result column="sub_id" property="subId" />
+        <result column="photo_num" property="photoNum" />
+        <result column="type" property="type" />
+        <result column="photo_url" property="photoUrl" />
+        <result column="callback_photo_url" property="callbackPhotoUrl" />
+        <result column="result" property="result" />
+        <result column="create_name" property="createName" />
+        <result column="create_by" property="createBy" />
+        <result column="create_time" property="createTime" />
+        <result column="update_name" property="updateName" />
+        <result column="update_by" property="updateBy" />
+        <result column="update_time" property="updateTime" />
+        <result column="is_deleted" property="isDeleted" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, log_id, sub_id, photo_num, type, photo_url, callback_photo_url, result, create_name, create_by, create_time, update_name, update_by, update_time, is_deleted
+    </sql>
+
+</mapper>

+ 49 - 0
zd-modules/zd-modules-laboratory/src/main/resources/mapper/laboratory/WarningNoticeLogMapper.xml

@@ -0,0 +1,49 @@
+<?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.zd.laboratory.mapper.WarningNoticeLogMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.zd.laboratory.domain.WarningNoticeLog">
+        <id column="id" property="id" />
+        <result column="key_id" property="keyId"/>
+        <result column="warning_content" property="warningContent" />
+        <result column="warning_type" property="warningType" />
+        <result column="warning_sub_type" property="warningSubType"/>
+        <result column="warning_way" property="warningWay" />
+        <result column="sub_id" property="subId" />
+        <result column="sub_name" property="subName" />
+        <result column="build_name" property="buildName" />
+        <result column="floor_name" property="floorName" />
+        <result column="room_num" property="roomNum" />
+        <result column="warning_time" property="warningTime" />
+        <result column="name" property="name" />
+        <result column="margin" property="margin" />
+        <result column="specification" property="specification" />
+        <result column="apply" property="apply" />
+        <result column="applyTime" property="applyTime" />
+        <result column="deposit" property="deposit" />
+        <result column="record_video" property="recordVideo" />
+        <result column="record_photo" property="recordPhoto" />
+        <result column="risk_duration" property="riskDuration" />
+        <result column="responder" property="responder" />
+        <result column="indoor_user" property="indoorUser" />
+        <result column="start_time" property="startTime"/>
+        <result column="end_time" property="endTime"/>
+        <result column="expiration_time" property="expirationTime"/>
+        <result column="entry_time" property="entryTime"/>
+        <result column="holder" property="holder"/>
+        <result column="create_name" property="createName" />
+        <result column="create_by" property="createBy" />
+        <result column="create_time" property="createTime" />
+        <result column="update_name" property="updateName" />
+        <result column="update_by" property="updateBy" />
+        <result column="update_time" property="updateTime" />
+        <result column="is_deleted" property="isDeleted" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, key_id, warning_content, warning_type, warning_sub_type, warning_way, sub_id, sub_name, build_name, floor_name, room_num, warning_time, name, margin, specification, apply, applyTime, deposit, record_video, record_photo, risk_duration, responder, indoor_user, start_time, end_time, expiration_time, entry_time, holder, create_name, create_by, create_time, update_name, update_by, update_time, is_deleted
+    </sql>
+
+</mapper>

+ 2 - 2
zd-modules/zd-security/src/main/java/com/zd/security/CodeGenerator.java

@@ -16,9 +16,9 @@ public class CodeGenerator {
 
     public static void main(String[] args) {
         //要生成的表名
-        String[] tables = {"sec_check_rectify"};
+        String[] tables = {"lab_warning_detail"};
         //表前缀,若不想生成在实体里,添加前缀,如:sys_user, 前缀为:sys_
-        String tablePrefix = "sec_";
+        String tablePrefix = "lab_";
         URL url = CodeGenerator.class.getResource("");
         MybatisPlusGenerator.generator(tables,tablePrefix, url);
     }