瀏覽代碼

优化首页接口逻辑,开发智能分析相关接口

james 1 天之前
父節點
當前提交
8ac594a9e2
共有 51 個文件被更改,包括 2514 次插入331 次删除
  1. 12 0
      service-sas/service-sas-biz/pom.xml
  2. 16 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/common/StandardOnvifService.java
  3. 126 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/common/UnityVideoInfo.java
  4. 126 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/common/dahua/DahuaVideoInfo.java
  5. 166 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/common/dahua/DahuaVideoStreamService.java
  6. 12 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/common/dahua/InitNetSDKLib.java
  7. 9 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/common/entity/DahuaNvrInfo.java
  8. 20 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/common/entity/DeviceVideoInfo.java
  9. 39 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/common/enums/BusinessEnum.java
  10. 22 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/common/enums/DeviceTypeEnum.java
  11. 23 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/common/enums/ProtocolEnum.java
  12. 32 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/common/enums/SystemTypeCodeEnum.java
  13. 86 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/common/exception/BusinessException.java
  14. 0 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/common/onvif
  15. 14 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/common/util/GetIpUtils.java
  16. 257 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/common/util/ZLMediaKitUtils.java
  17. 14 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/config/RestTemplateConfig.java
  18. 108 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/controller/web/MybatisGeneratorUtils.java
  19. 64 9
      service-sas/service-sas-biz/src/main/java/com/usky/sas/controller/web/SasHomepageController.java
  20. 24 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasCarTypeCode.java
  21. 24 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasCertifiedTypeCode.java
  22. 1 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasEntranceEventCode.java
  23. 1 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasPatrolEventCode.java
  24. 1 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasPerceptionEventCode.java
  25. 25 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasPersonTypeCode.java
  26. 39 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasPic.java
  27. 24 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasPlateColor.java
  28. 24 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasPlateTypeCode.java
  29. 1 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasSnapTypeCode.java
  30. 7 9
      service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasSystemConfig.java
  31. 10 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasCarTypeCodeMapper.java
  32. 10 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasCertifiedTypeCodeMapper.java
  33. 3 8
      service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasGisMapper.java
  34. 10 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasPersonTypeCodeMapper.java
  35. 10 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasPicMapper.java
  36. 10 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasPlateColorMapper.java
  37. 10 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasPlateTypeCodeMapper.java
  38. 1 1
      service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasSystemConfigMapper.java
  39. 22 6
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/SasHomepageService.java
  40. 12 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/SasIntelligentService.java
  41. 807 33
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/impl/SasHomepageServiceImpl.java
  42. 0 264
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/impl/SasIntelligentServiceImpl.java
  43. 1 1
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/impl/SasOneStandardSixRealitiesServiceImpl.java
  44. 144 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/EventDetailResponse.java
  45. 15 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/HomepageAlertHistoryRequest.java
  46. 5 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/IntelligentEventItem.java
  47. 21 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/IntelligentEventPageRequest.java
  48. 66 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/SystemResourceResponse.java
  49. 18 0
      service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/VideoStreamVo.java
  50. 10 0
      service-sas/service-sas-biz/src/main/resources/mapper/sas/SasPersonTypeCodeMapper.xml
  51. 12 0
      service-sas/service-sas-biz/src/main/resources/mapper/sas/SasSnapTypeCodeMapper.xml

+ 12 - 0
service-sas/service-sas-biz/pom.xml

@@ -75,6 +75,18 @@
             <artifactId>hutool-all</artifactId>
         </dependency>
 
+        <!-- JNA -->
+        <dependency>
+            <groupId>net.java.dev.jna</groupId>
+            <artifactId>jna</artifactId>
+            <version>5.13.0</version>
+        </dependency>
+        <dependency>
+            <groupId>net.java.dev.jna</groupId>
+            <artifactId>jna-platform</artifactId>
+            <version>5.13.0</version>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 16 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/common/StandardOnvifService.java

@@ -0,0 +1,16 @@
+package com.usky.sas.common;
+
+import org.springframework.stereotype.Service;
+
+@Service
+public class StandardOnvifService {
+    public String getNvrRealTimeStreamUrl(String ip, String user, String password, String token) {
+        // Placeholder implementation
+        return String.format("rtsp://%s:%s@%s:554/stream/%s", user, password, ip, token);
+    }
+
+    public String getRealTimeStreamUrl(String ip, String user, String password) {
+        // Placeholder implementation
+        return String.format("rtsp://%s:%s@%s:554/stream", user, password, ip);
+    }
+}

+ 126 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/common/UnityVideoInfo.java

@@ -0,0 +1,126 @@
+package com.usky.sas.common;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class UnityVideoInfo {
+    @ApiModelProperty("设备mac地址")
+    private String macAddr;
+    @ApiModelProperty("ZLM主动拉流唯一标识")
+    private String key;
+    @ApiModelProperty("视频流唯一标识")
+    private String ssrc;
+    @ApiModelProperty("视频流播放地址")
+    private String url;
+
+    public UnityVideoInfo() {
+    }
+
+    public String getMacAddr() {
+        return this.macAddr;
+    }
+
+    public String getKey() {
+        return this.key;
+    }
+
+    public String getSsrc() {
+        return this.ssrc;
+    }
+
+    public String getUrl() {
+        return this.url;
+    }
+
+    public void setMacAddr(String macAddr) {
+        this.macAddr = macAddr;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public void setSsrc(String ssrc) {
+        this.ssrc = ssrc;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        } else if (!(o instanceof UnityVideoInfo)) {
+            return false;
+        } else {
+            UnityVideoInfo other = (UnityVideoInfo)o;
+            if (!other.canEqual(this)) {
+                return false;
+            } else {
+                Object this$macAddr = this.getMacAddr();
+                Object other$macAddr = other.getMacAddr();
+                if (this$macAddr == null) {
+                    if (other$macAddr != null) {
+                        return false;
+                    }
+                } else if (!this$macAddr.equals(other$macAddr)) {
+                    return false;
+                }
+
+                Object this$key = this.getKey();
+                Object other$key = other.getKey();
+                if (this$key == null) {
+                    if (other$key != null) {
+                        return false;
+                    }
+                } else if (!this$key.equals(other$key)) {
+                    return false;
+                }
+
+                Object this$ssrc = this.getSsrc();
+                Object other$ssrc = other.getSsrc();
+                if (this$ssrc == null) {
+                    if (other$ssrc != null) {
+                        return false;
+                    }
+                } else if (!this$ssrc.equals(other$ssrc)) {
+                    return false;
+                }
+
+                Object this$url = this.getUrl();
+                Object other$url = other.getUrl();
+                if (this$url == null) {
+                    if (other$url != null) {
+                        return false;
+                    }
+                } else if (!this$url.equals(other$url)) {
+                    return false;
+                }
+
+                return true;
+            }
+        }
+    }
+
+    protected boolean canEqual(Object other) {
+        return other instanceof UnityVideoInfo;
+    }
+
+    public int hashCode() {
+        int PRIME = 59;
+        int result = 1;
+        Object $macAddr = this.getMacAddr();
+        result = result * 59 + ($macAddr == null ? 43 : $macAddr.hashCode());
+        Object $key = this.getKey();
+        result = result * 59 + ($key == null ? 43 : $key.hashCode());
+        Object $ssrc = this.getSsrc();
+        result = result * 59 + ($ssrc == null ? 43 : $ssrc.hashCode());
+        Object $url = this.getUrl();
+        result = result * 59 + ($url == null ? 43 : $url.hashCode());
+        return result;
+    }
+
+    public String toString() {
+        return "UnityVideoInfo(macAddr=" + this.getMacAddr() + ", key=" + this.getKey() + ", ssrc=" + this.getSsrc() + ", url=" + this.getUrl() + ")";
+    }
+}

+ 126 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/common/dahua/DahuaVideoInfo.java

@@ -0,0 +1,126 @@
+package com.usky.sas.common.dahua;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class DahuaVideoInfo {
+    @ApiModelProperty("设备mac地址")
+    private String macAddr;
+    @ApiModelProperty("视频流句柄")
+    private Long handle;
+    @ApiModelProperty("视频流唯一标识")
+    private String ssrc;
+    @ApiModelProperty("视频流播放地址")
+    private String url;
+
+    public DahuaVideoInfo() {
+    }
+
+    public String getMacAddr() {
+        return this.macAddr;
+    }
+
+    public Long getHandle() {
+        return this.handle;
+    }
+
+    public String getSsrc() {
+        return this.ssrc;
+    }
+
+    public String getUrl() {
+        return this.url;
+    }
+
+    public void setMacAddr(String macAddr) {
+        this.macAddr = macAddr;
+    }
+
+    public void setHandle(Long handle) {
+        this.handle = handle;
+    }
+
+    public void setSsrc(String ssrc) {
+        this.ssrc = ssrc;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        } else if (!(o instanceof DahuaVideoInfo)) {
+            return false;
+        } else {
+            DahuaVideoInfo other = (DahuaVideoInfo)o;
+            if (!other.canEqual(this)) {
+                return false;
+            } else {
+                Object this$macAddr = this.getMacAddr();
+                Object other$macAddr = other.getMacAddr();
+                if (this$macAddr == null) {
+                    if (other$macAddr != null) {
+                        return false;
+                    }
+                } else if (!this$macAddr.equals(other$macAddr)) {
+                    return false;
+                }
+
+                Object this$handle = this.getHandle();
+                Object other$handle = other.getHandle();
+                if (this$handle == null) {
+                    if (other$handle != null) {
+                        return false;
+                    }
+                } else if (!this$handle.equals(other$handle)) {
+                    return false;
+                }
+
+                Object this$ssrc = this.getSsrc();
+                Object other$ssrc = other.getSsrc();
+                if (this$ssrc == null) {
+                    if (other$ssrc != null) {
+                        return false;
+                    }
+                } else if (!this$ssrc.equals(other$ssrc)) {
+                    return false;
+                }
+
+                Object this$url = this.getUrl();
+                Object other$url = other.getUrl();
+                if (this$url == null) {
+                    if (other$url != null) {
+                        return false;
+                    }
+                } else if (!this$url.equals(other$url)) {
+                    return false;
+                }
+
+                return true;
+            }
+        }
+    }
+
+    protected boolean canEqual(Object other) {
+        return other instanceof DahuaVideoInfo;
+    }
+
+    public int hashCode() {
+        int PRIME = 59;
+        int result = 1;
+        Object $macAddr = this.getMacAddr();
+        result = result * 59 + ($macAddr == null ? 43 : $macAddr.hashCode());
+        Object $handle = this.getHandle();
+        result = result * 59 + ($handle == null ? 43 : $handle.hashCode());
+        Object $ssrc = this.getSsrc();
+        result = result * 59 + ($ssrc == null ? 43 : $ssrc.hashCode());
+        Object $url = this.getUrl();
+        result = result * 59 + ($url == null ? 43 : $url.hashCode());
+        return result;
+    }
+
+    public String toString() {
+        return "DahuaVideoInfo(macAddr=" + this.getMacAddr() + ", handle=" + this.getHandle() + ", ssrc=" + this.getSsrc() + ", url=" + this.getUrl() + ")";
+    }
+}

+ 166 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/common/dahua/DahuaVideoStreamService.java

@@ -0,0 +1,166 @@
+package com.usky.sas.common.dahua;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.usky.sas.common.util.GetIpUtils;
+import com.usky.sas.service.vo.VideoStreamVo;
+import com.usky.sas.common.exception.BusinessException;
+import com.usky.sas.common.entity.DahuaNvrInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static java.lang.Long.toHexString;
+
+@Component
+public class DahuaVideoStreamService {
+    private static final Logger log = LoggerFactory.getLogger(DahuaVideoStreamService.class);
+    
+    // Placeholder constants and maps
+    public static class Constant {
+        public static long globalSsrc = 0;
+    }
+    
+    // Placeholder StreamContext
+    public static class StreamContext {
+        public long ssrc;
+        public StreamContext(String ip, int port) throws IOException {}
+        public void close() {}
+    }
+    
+    // Placeholder FPlayDataCallBackEx
+    public static class FPlayDataCallBackEx implements NetSDKLib.fDataCallBack {
+        public FPlayDataCallBackEx(StreamContext context, String mac) {}
+        public int invoke(Long lPlayHandle, int dwDataType, byte[] pBuffer, int dwBufSize, int dwUser) { return 0; }
+    }
+
+    // Placeholder NetSDKLib interface
+    public interface NetSDKLib {
+        interface fDataCallBack {
+            int invoke(Long lPlayHandle, int dwDataType, byte[] pBuffer, int dwBufSize, int dwUser);
+        }
+        class NET_TIME {
+            public void setTime(int year, int month, int day, int hour, int minute, int second) {}
+        }
+        class NET_IN_PLAYBACK_BY_DATA_TYPE {
+            public int emDataType;
+            public int nChannelID;
+            public NET_TIME stStartTime;
+            public NET_TIME stStopTime;
+            public int nPlayDirection;
+            public Object dwPosUser;
+            public Object hWnd;
+            public Object cbDownLoadPos;
+            public fDataCallBack fDownLoadDataCallBack;
+            public Object fDownLoadDataCallBackEx;
+            public Object dwDataUser;
+        }
+        class NET_OUT_PLAYBACK_BY_DATA_TYPE {}
+        
+        Long CLIENT_PlayBackByDataType(Long userID, NET_IN_PLAYBACK_BY_DATA_TYPE stIn, NET_OUT_PLAYBACK_BY_DATA_TYPE stOut, int timeout);
+        int CLIENT_GetLastError();
+        boolean CLIENT_StopPlayBack(Long lPlayHandle);
+    }
+    
+    // Mocking InitNetSDKLib.dhNetSDK
+    public static class InitNetSDKLib {
+        public static NetSDKLib dhNetSDK = new NetSDKLib() {
+            @Override
+            public Long CLIENT_PlayBackByDataType(Long userID, NET_IN_PLAYBACK_BY_DATA_TYPE stIn, NET_OUT_PLAYBACK_BY_DATA_TYPE stOut, int timeout) { return 1L; }
+            @Override
+            public int CLIENT_GetLastError() { return 0; }
+            @Override
+            public boolean CLIENT_StopPlayBack(Long lPlayHandle) { return true; }
+        };
+    }
+
+    static Map<String, NetSDKLib.fDataCallBack> dahuaPlayDataCallBackMap = new ConcurrentHashMap<>();
+    static Map<String, StreamContext> streamContextMap = new ConcurrentHashMap<>();
+    static Map<String, Object> dahuaVideoInfo = new ConcurrentHashMap<>();
+
+    public static VideoStreamVo playBackByTime(String oldMac, String macAddr, Long userID, int lChannel, int mediaRtpPort, Integer mediaHttpPort, Date beginTime, Date endTime) {
+        if (StrUtil.isNotBlank(oldMac) && streamContextMap.containsKey(oldMac)) {
+            streamContextMap.get(oldMac).close();
+            streamContextMap.remove(oldMac);
+            dahuaPlayDataCallBackMap.remove(oldMac);
+        }
+
+        StreamContext context = null;
+        try {
+            context = new StreamContext(GetIpUtils.getServerIP(), mediaRtpPort);
+            log.info("设备 {} RTP连接已建立: {}:{}", new Object[]{macAddr, GetIpUtils.getServerIP(), mediaRtpPort});
+        } catch (IOException e) {
+            log.error("设备 {} 连接失败: {}", macAddr, e.getMessage());
+            throw new BusinessException("设备 " + macAddr + " 连接失败", -1);
+        }
+
+        String newMac = macAddr + System.currentTimeMillis();
+        Constant.globalSsrc = Constant.globalSsrc >= 4294967295L ? 65535L : Constant.globalSsrc + 1L;
+        context.ssrc = Constant.globalSsrc;
+        streamContextMap.put(newMac, context);
+        FPlayDataCallBackEx playDataCallBack = new FPlayDataCallBackEx(context, newMac);
+        dahuaPlayDataCallBackMap.put(newMac, playDataCallBack);
+
+        NetSDKLib.NET_IN_PLAYBACK_BY_DATA_TYPE stIn = new NetSDKLib.NET_IN_PLAYBACK_BY_DATA_TYPE();
+        int beginYear = DateUtil.year(beginTime);
+        int beginMonth = DateUtil.month(beginTime) + 1;
+        int beginDay = DateUtil.dayOfMonth(beginTime);
+        int beginHour = DateUtil.hour(beginTime, true);
+        int beginMinute = DateUtil.minute(beginTime);
+        int beginSecond = DateUtil.second(beginTime);
+        NetSDKLib.NET_TIME begin = new NetSDKLib.NET_TIME();
+        begin.setTime(beginYear, beginMonth, beginDay, beginHour, beginMinute, beginSecond);
+        int endYear = DateUtil.year(endTime);
+        int endMonth = DateUtil.month(endTime) + 1;
+        int endDay = DateUtil.dayOfMonth(endTime);
+        int endHour = DateUtil.hour(endTime, true);
+        int endMinute = DateUtil.minute(endTime);
+        int endSecond = DateUtil.second(endTime);
+        NetSDKLib.NET_TIME end = new NetSDKLib.NET_TIME();
+        end.setTime(endYear, endMonth, endDay, endHour, endMinute, endSecond);
+        
+        stIn.stStartTime = begin;
+        stIn.stStopTime = end;
+        
+        NetSDKLib.NET_OUT_PLAYBACK_BY_DATA_TYPE stOut = new NetSDKLib.NET_OUT_PLAYBACK_BY_DATA_TYPE();
+        Long lPlayHandle = InitNetSDKLib.dhNetSDK.CLIENT_PlayBackByDataType(userID, stIn, stOut, 5000);
+        
+        if (lPlayHandle != 0L) {
+            log.info("回放取流成功,回放句柄:{}", lPlayHandle);
+            log.info("取流成功,播放地址:" + GetIpUtils.getServerIP() + ":" + mediaHttpPort + "/index/api/webrtc?app=rtp&stream=" + context.ssrc + "&type=play");
+            VideoStreamVo streamVo = new VideoStreamVo();
+            streamVo.setHandle(lPlayHandle);
+            streamVo.setMac(newMac);
+            streamVo.setUrl("http://" + GetIpUtils.getServerIP() + ":" + mediaHttpPort + "/index/api/webrtc?app=rtp&stream=" + toHexString(context.ssrc) + "&type=play");
+            DahuaVideoInfo videoInfo = new DahuaVideoInfo();
+            videoInfo.setSsrc(toHexString(context.ssrc));
+            videoInfo.setUrl("http://" + GetIpUtils.getServerIP() + ":" + mediaHttpPort + "/index/api/webrtc?app=rtp&stream=" + toHexString(context.ssrc) + "&type=play");
+            videoInfo.setHandle(lPlayHandle);
+            dahuaVideoInfo.put(newMac, videoInfo);
+            return streamVo;
+        } else {
+            log.info("回放取流失败,原因码:{}", InitNetSDKLib.dhNetSDK.CLIENT_GetLastError());
+            throw new BusinessException("回放失败", -1);
+        }
+    }
+
+    public static void stopPlayStreamData(Long PlayHandle, String macAddr) {
+        if (PlayHandle != 0L) {
+            if (!InitNetSDKLib.dhNetSDK.CLIENT_StopPlayBack(PlayHandle)) {
+                log.error("停止取流失败,err:" + InitNetSDKLib.dhNetSDK.CLIENT_GetLastError());
+            } else {
+                log.info("停止取流成功");
+                StreamContext context = streamContextMap.get(macAddr);
+                if (context != null) {
+                    context.close();
+                }
+                dahuaPlayDataCallBackMap.remove(macAddr);
+            }
+        }
+    }
+}

+ 12 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/common/dahua/InitNetSDKLib.java

@@ -0,0 +1,12 @@
+package com.usky.sas.common.dahua;
+
+import com.usky.sas.common.entity.DahuaNvrInfo;
+
+public class InitNetSDKLib {
+    public static Integer getIpcChannel(Long loginHandle, String ip, Integer maxChannel) {
+        return 1;
+    }
+    public static DahuaNvrInfo nvrLogin(String ip, Integer port, String user, String password, String deviceId) {
+        return new DahuaNvrInfo();
+    }
+}

+ 9 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/common/entity/DahuaNvrInfo.java

@@ -0,0 +1,9 @@
+package com.usky.sas.common.entity;
+
+import lombok.Data;
+
+@Data
+public class DahuaNvrInfo {
+    private Long loginHandle;
+    private Integer maxChannelNum;
+}

+ 20 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/common/entity/DeviceVideoInfo.java

@@ -0,0 +1,20 @@
+package com.usky.sas.common.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class DeviceVideoInfo {
+    @ApiModelProperty("登录句柄")
+    private Integer userId;
+    @ApiModelProperty("同步源标识符")
+    private String ssrc;
+    @ApiModelProperty("视频流句柄")
+    private Integer handle;
+    @ApiModelProperty("播放地址")
+    private String url;
+    @ApiModelProperty("视频码率")
+    private Integer bitrate;
+    @ApiModelProperty("视频流类型 1实时预览 2回放")
+    private Integer streamType;
+}

+ 39 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/common/enums/BusinessEnum.java

@@ -0,0 +1,39 @@
+package com.usky.sas.common.enums;
+
+public enum BusinessEnum {
+    USER_NOT_EXIST(-1001, "账号不存在"),
+    USER_EXIST(-1002, "账号已存在"),
+    PASSWORD_ERROR(-1003, "用户名或密码错误"),
+    ADD_FAIL(-1004, "新增失败"),
+    UPDATE_FAIL(-1005, "更新失败"),
+    DELETE_FAIL(-1006, "删除失败"),
+    SYSTEM_NOT_ACTIVATION(-1007, "系统未激活"),
+    LICENSE_NULL(-1008, "激活码不能为空"),
+    LICENSE_EXPIRE(-1009, "系统激活码已过期"),
+    UNAUTHORIZED_LICENSE(-1010, "无效激活码"),
+    MQTT_CONNECT_FAIL(-1011, "Mqtt连接失败"),
+    MQTT_UN_CONNECT(-1012, "Mqtt连接未初始化"),
+    MQTT_PAUSE_FAIL(-1013, "暂停Mqtt事件订阅错误"),
+    MQTT_RESUME_FAIL(-1014, "恢复Mqtt事件订阅错误"),
+    EXIST(-1015, "重复添加"),
+    DEVICE_NOT_ACTIVATION(-1016, "设备未激活"),
+    DEVICE_ACTIVATION_EXPIRE(-1017, "设备激活已过期"),
+    DEVICE_ACTIVATION_FAILED(-1018, "设备激活失败"),
+    DEVICE_NOT_LOGIN(-1019, "设备未注册");
+
+    private int code;
+    private String description;
+
+    private BusinessEnum(int code, String description) {
+        this.code = code;
+        this.description = description;
+    }
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getDescription() {
+        return this.description;
+    }
+}

+ 22 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/common/enums/DeviceTypeEnum.java

@@ -0,0 +1,22 @@
+package com.usky.sas.common.enums;
+
+public enum DeviceTypeEnum {
+    IPC(1, "IPC"),
+    NVR(2, "NVR");
+
+    private final Integer code;
+    private final String desc;
+
+    DeviceTypeEnum(Integer code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+}

+ 23 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/common/enums/ProtocolEnum.java

@@ -0,0 +1,23 @@
+package com.usky.sas.common.enums;
+
+public enum ProtocolEnum {
+    ONVIF(1, "onvif"),
+    HIK(2, "海康"),
+    DA_HUA(3, "大华");
+
+    private final Integer code;
+    private final String desc;
+
+    private ProtocolEnum(Integer code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public Integer getCode() {
+        return this.code;
+    }
+
+    public String getDesc() {
+        return this.desc;
+    }
+}

+ 32 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/common/enums/SystemTypeCodeEnum.java

@@ -0,0 +1,32 @@
+package com.usky.sas.common.enums;
+
+public enum SystemTypeCodeEnum {
+    snap(1001, "实时智能分析"),
+    video(1002, "视频安防监控"),
+    usb(1003, "视频导出防护"),
+    gauth(1004, "组合认证控制"),
+    entrance(1005, "出入门禁控制"),
+    parking(1006, "车牌抓拍分析"),
+    alarm(1007, "入侵紧急报警"),
+    patrol(1008, "实时电子巡检"),
+    perception(1009, "状态感知探测"),
+    acquisition(1010, "数据采集探测"),
+    collection(1011, "状态采集探测"),
+    roadblock(1012, "阻车路障探测");
+
+    private final int code;
+    private final String message;
+
+    private SystemTypeCodeEnum(int code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getMessage() {
+        return this.message;
+    }
+}

+ 86 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/common/exception/BusinessException.java

@@ -0,0 +1,86 @@
+package com.usky.sas.common.exception;
+
+
+import com.usky.sas.common.enums.BusinessEnum;
+
+public class BusinessException extends RuntimeException {
+    private String message;
+    private int code;
+
+    public BusinessException(int code, String message) {
+        super(message);
+        this.code = code;
+    }
+
+    public BusinessException(String message, int code) {
+        this.message = message;
+        this.code = code;
+    }
+
+    public BusinessException(BusinessEnum businessEnum) {
+        this.message = businessEnum.getDescription();
+        this.code = businessEnum.getCode();
+    }
+
+    public String getMessage() {
+        return this.message;
+    }
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        } else if (!(o instanceof BusinessException)) {
+            return false;
+        } else {
+            BusinessException other = (BusinessException)o;
+            if (!other.canEqual(this)) {
+                return false;
+            } else {
+                Object this$message = this.getMessage();
+                Object other$message = other.getMessage();
+                if (this$message == null) {
+                    if (other$message != null) {
+                        return false;
+                    }
+                } else if (!this$message.equals(other$message)) {
+                    return false;
+                }
+
+                if (this.getCode() != other.getCode()) {
+                    return false;
+                } else {
+                    return true;
+                }
+            }
+        }
+    }
+
+    protected boolean canEqual(Object other) {
+        return other instanceof BusinessException;
+    }
+
+    public int hashCode() {
+        int PRIME = 59;
+        int result = 1;
+        Object $message = this.getMessage();
+        result = result * 59 + ($message == null ? 43 : $message.hashCode());
+        result = result * 59 + this.getCode();
+        return result;
+    }
+
+    public String toString() {
+        return "BusinessException(message=" + this.getMessage() + ", code=" + this.getCode() + ")";
+    }
+}

+ 0 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/common/onvif


+ 14 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/common/util/GetIpUtils.java

@@ -0,0 +1,14 @@
+package com.usky.sas.common.util;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+public class GetIpUtils {
+    public static String getServerIP() {
+        try {
+            return InetAddress.getLocalHost().getHostAddress();
+        } catch (UnknownHostException e) {
+            return "127.0.0.1";
+        }
+    }
+}

+ 257 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/common/util/ZLMediaKitUtils.java

@@ -0,0 +1,257 @@
+package com.usky.sas.common.util;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.usky.sas.common.dahua.DahuaVideoStreamService;
+// import com.fjkj.agcp.common.global.GlobalMemoryMap; // Replaced
+import com.usky.sas.common.UnityVideoInfo;
+import java.util.concurrent.ConcurrentHashMap; // Added
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import com.usky.sas.common.exception.BusinessException;
+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.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+@Component
+public class ZLMediaKitUtils {
+    private static final Logger log = LoggerFactory.getLogger(ZLMediaKitUtils.class);
+    @Autowired
+    private RestTemplate restTemplate;
+    @Value("${media-kit.http.port}")
+    private Integer mediaHttpPort;
+    static Map<String, UnityVideoInfo> unityVideoInfo;
+
+    public ZLMediaKitUtils() {
+    }
+
+    public boolean streamIsExist(String mediaIp, Integer mediaHttpPort, String secret, String ssrc) {
+        try {
+            String url = String.format("http://%s:%d/index/api/getMediaList?secret=%s&app=rtp&stream=%s", mediaIp, mediaHttpPort, secret, ssrc);
+            ResponseEntity<JsonNode> response = this.restTemplate.getForEntity(url, JsonNode.class, new Object[0]);
+            if (!response.getStatusCode().is2xxSuccessful()) {
+                log.error("获取流列表失败: {}", response.getStatusCode());
+                return false;
+            } else {
+                JsonNode dataNode = ((JsonNode)Objects.requireNonNull(response.getBody())).path("data");
+                return dataNode.isArray() && !dataNode.isEmpty();
+            }
+        } catch (Exception e) {
+            log.error("检查流是否存在失败", e);
+            return false;
+        }
+    }
+
+    public boolean streamIsUsed(String mediaIp, Integer mediaHttpPort, String secret, String ssrc, Long playHandle, String macAddr, boolean isPlayback) {
+        try {
+            String url = String.format("http://%s:%d/index/api/getMediaPlayerList?secret=%s&schema=rtsp&vhost=__defaultVhost__&app=rtp&stream=%s", mediaIp, mediaHttpPort, secret, ssrc);
+            ResponseEntity<JsonNode> response = this.restTemplate.getForEntity(url, JsonNode.class, new Object[0]);
+            if (!response.getStatusCode().is2xxSuccessful()) {
+                log.error("获取播放器列表失败: {}", response.getStatusCode());
+                return false;
+            }
+
+            JsonNode dataNode = ((JsonNode)response.getBody()).path("data");
+            if (dataNode.isArray() && dataNode.size() == 0) {
+                log.info("没有客户端在观看,即将关闭流: {}", ssrc);
+                //HikVideoStreamService.stopPlayStreamData(playHandle, macAddr);
+                return true;
+            }
+        } catch (Exception e) {
+            log.error("检查或关闭流失败", e);
+        }
+
+        return false;
+    }
+
+    public boolean dahuaStreamIsUsed(String mediaIp, Integer mediaHttpPort, String secret, String ssrc, Long playHandle, String macAddr, boolean isPlayback) {
+        try {
+            String url = String.format("http://%s:%d/index/api/getMediaPlayerList?secret=%s&schema=rtsp&vhost=__defaultVhost__&app=rtp&stream=%s", mediaIp, mediaHttpPort, secret, ssrc);
+            ResponseEntity<JsonNode> response = this.restTemplate.getForEntity(url, JsonNode.class, new Object[0]);
+            if (!response.getStatusCode().is2xxSuccessful()) {
+                log.error("获取播放器列表失败: {}", response.getStatusCode());
+                return false;
+            }
+
+            JsonNode dataNode = ((JsonNode)response.getBody()).path("data");
+            if (dataNode.isArray() && dataNode.size() == 0) {
+                log.info("没有客户端在观看,即将关闭流: {}", ssrc);
+                DahuaVideoStreamService.stopPlayStreamData(playHandle, macAddr);
+                return true;
+            }
+        } catch (Exception e) {
+            log.error("检查或关闭流失败", e);
+        }
+
+        return false;
+    }
+
+    public String addStreamProxy(String secret, String streamSsrc, String rtspUrl, String username, String password) {
+        try {
+            URI originalUri = new URI(rtspUrl);
+            String userInfo = username + ":" + password;
+            URI newUri = new URI(originalUri.getScheme(), userInfo, originalUri.getHost(), originalUri.getPort(), originalUri.getPath(), originalUri.getQuery(), originalUri.getFragment());
+            String newRtspUrl = newUri.toString();
+            String zlmApiUrl = "http://" + GetIpUtils.getServerIP() + ":" + this.mediaHttpPort + "/index/api/addStreamProxy";
+            Map<String, Object> body = new HashMap();
+            body.put("vhost", "__defaultVhost__");
+            body.put("app", "rtp");
+            body.put("stream", streamSsrc);
+            body.put("url", newRtspUrl);
+            body.put("secret", secret);
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            HttpEntity<Map<String, Object>> request = new HttpEntity(body, headers);
+            ResponseEntity<Map> response = this.restTemplate.postForEntity(zlmApiUrl, request, Map.class, new Object[0]);
+            if (response.getStatusCode().is2xxSuccessful()) {
+                Map<String, Object> responseBody = (Map)response.getBody();
+                if (responseBody != null && "0".equals(String.valueOf(responseBody.get("code")))) {
+                    log.info("ZLM 拉流成功: " + responseBody);
+                    return "__defaultVhost__/rtp/" + streamSsrc;
+                } else {
+                    log.error(" ZLM 拉流失败: " + responseBody);
+                    throw new BusinessException("播放失败", -1);
+                }
+            } else {
+                log.error("HTTP 请求失败: " + response.getStatusCode());
+                throw new BusinessException("播放失败", -1);
+            }
+        } catch (URISyntaxException e) {
+            log.error(" URL 解析错误: " + e.getMessage());
+            throw new BusinessException("播放失败", -1);
+        } catch (Exception e) {
+            log.error(" 调用 ZLM API 异常: " + e.getMessage());
+            throw new BusinessException(" 播放失败 ", -1);
+        }
+    }
+
+    public String addStreamUnityProxy(String secret, String streamSsrc, String rtspUrl) {
+        try {
+            String zlmApiUrl = "http://" + GetIpUtils.getServerIP() + ":" + this.mediaHttpPort + "/index/api/addStreamProxy";
+            Map<String, Object> body = new HashMap();
+            body.put("vhost", "__defaultVhost__");
+            body.put("app", "rtp");
+            body.put("stream", streamSsrc);
+            body.put("url", rtspUrl);
+            body.put("secret", secret);
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            HttpEntity<Map<String, Object>> request = new HttpEntity(body, headers);
+            ResponseEntity<Map> response = this.restTemplate.postForEntity(zlmApiUrl, request, Map.class, new Object[0]);
+            if (response.getStatusCode().is2xxSuccessful()) {
+                Map<String, Object> responseBody = (Map)response.getBody();
+                if (responseBody != null && "0".equals(String.valueOf(responseBody.get("code")))) {
+                    log.info("ZLM 拉流成功: " + responseBody);
+                    return "__defaultVhost__/rtp/" + streamSsrc;
+                } else {
+                    log.error(" ZLM 拉流失败: " + responseBody);
+                    throw new BusinessException("播放失败", -1);
+                }
+            } else {
+                log.error("HTTP 请求失败: " + response);
+                throw new BusinessException("播放失败", -1);
+            }
+        } catch (Exception e) {
+            log.error(" 调用 ZLM API 异常: " + e.getMessage());
+            throw new BusinessException("播放失败", -1);
+        }
+    }
+
+    public String addPlayStreamProxy(String secret, String streamSsrc, String rtspUrl, String username, String password, LocalDateTime startTime, LocalDateTime endTime) {
+        try {
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'");
+            String startStr = startTime.atOffset(ZoneOffset.UTC).format(formatter);
+            String endStr = endTime.atOffset(ZoneOffset.UTC).format(formatter);
+            String timeParams = "?starttime=" + startStr + "&endtime=" + endStr;
+            if (rtspUrl.contains("?")) {
+                rtspUrl = rtspUrl.substring(0, rtspUrl.indexOf(63));
+            }
+
+            String fullRtspUrl = rtspUrl + timeParams;
+            URI originalUri = new URI(fullRtspUrl);
+            String userInfo = username + ":" + password;
+            URI newUri = new URI(originalUri.getScheme(), userInfo, originalUri.getHost(), originalUri.getPort(), originalUri.getPath(), originalUri.getQuery(), originalUri.getFragment());
+            String newRtspUrl = newUri.toString();
+            String zlmApiUrl = "http://" + GetIpUtils.getServerIP() + ":" + this.mediaHttpPort + "/index/api/addStreamProxy";
+            Map<String, Object> body = new HashMap();
+            body.put("vhost", "__defaultVhost__");
+            body.put("app", "rtp");
+            body.put("stream", streamSsrc);
+            body.put("url", newRtspUrl);
+            body.put("secret", secret);
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            HttpEntity<Map<String, Object>> request = new HttpEntity(body, headers);
+            ResponseEntity<Map> response = this.restTemplate.postForEntity(zlmApiUrl, request, Map.class, new Object[0]);
+            if (response.getStatusCode().is2xxSuccessful()) {
+                Map<String, Object> responseBody = (Map)response.getBody();
+                if (responseBody != null && "0".equals(String.valueOf(responseBody.get("code")))) {
+                    log.info("ZLM 拉流成功: " + responseBody);
+                    return "__defaultVhost__/rtp/" + streamSsrc;
+                } else {
+                    log.error(" 拉流失败,请检查设备IP、用户名、密码、通道 是否正确,更多详细信息请看日志: " + responseBody);
+                    throw new BusinessException("播放失败", -1);
+                }
+            } else {
+                log.error("HTTP 请求失败: " + response.getStatusCode());
+                throw new BusinessException("播放失败", -1);
+            }
+        } catch (URISyntaxException e) {
+            log.error(" URL 解析错误: " + e.getMessage());
+            throw new BusinessException(" 播放失败", -1);
+        } catch (Exception e) {
+            log.error(" 调用 ZLM API 异常: " + e.getMessage());
+            throw new BusinessException(" 播放失败", -1);
+        }
+    }
+
+    public void unityStreamProxyIsUsed(String mediaIp, Integer mediaHttpPort, String secret, String ssrc, String key, String macAddr) {
+        try {
+            String listUrl = String.format("http://%s:%d/index/api/getMediaPlayerList?secret=%s&schema=rtsp&vhost=__defaultVhost__&app=rtp&stream=%s", mediaIp, mediaHttpPort, secret, ssrc);
+            ResponseEntity<JsonNode> listResponse = this.restTemplate.getForEntity(listUrl, JsonNode.class, new Object[0]);
+            if (!listResponse.getStatusCode().is2xxSuccessful()) {
+                log.warn("获取播放器列表失败: {}", listResponse.getStatusCode());
+                return;
+            }
+
+            JsonNode dataNode = ((JsonNode)Objects.requireNonNull(listResponse.getBody())).path("data");
+            if (dataNode.isArray() && dataNode.isEmpty()) {
+                log.info("没有客户端在观看,即将关闭流: {}", ssrc);
+                String delUrl = String.format("http://%s:%d/index/api/delStreamProxy?secret=%s&key=%s", mediaIp, mediaHttpPort, secret, key);
+                ResponseEntity<JsonNode> delResponse = this.restTemplate.getForEntity(delUrl, JsonNode.class, new Object[0]);
+                if (!delResponse.getStatusCode().is2xxSuccessful()) {
+                    log.warn("删除流代理失败: {}", delResponse.getStatusCode());
+                    return;
+                }
+
+                boolean flag = ((JsonNode)Objects.requireNonNull(delResponse.getBody())).path("data").path("flag").asBoolean(false);
+                if (flag) {
+                    unityVideoInfo.remove(macAddr);
+                    log.info("成功关闭设备{}拉流代理", macAddr);
+                } else {
+                    log.error("关闭设备{}拉流代理失败", macAddr);
+                }
+            }
+        } catch (Exception e) {
+            log.error("检查或关闭实时预览流失败", e);
+        }
+
+    }
+
+    static {
+        unityVideoInfo = new ConcurrentHashMap<>();
+    }
+}

+ 14 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/config/RestTemplateConfig.java

@@ -0,0 +1,14 @@
+package com.usky.sas.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class RestTemplateConfig {
+
+    @Bean
+    public RestTemplate restTemplate() {
+        return new RestTemplate();
+    }
+}

+ 108 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/controller/web/MybatisGeneratorUtils.java

@@ -0,0 +1,108 @@
+package com.usky.sas.controller.web;//package com.usky.iot.controller;//package com.usky.dm.controller.web.business;//package com.usky.dm.controller.web;
+
+
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.generator.AutoGenerator;
+import com.baomidou.mybatisplus.generator.InjectionConfig;
+import com.baomidou.mybatisplus.generator.config.*;
+import com.baomidou.mybatisplus.generator.config.po.TableInfo;
+import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author yq
+ * @date 2021/7/6 11:42
+ */
+public class MybatisGeneratorUtils {
+    public static void main(String[] args) {
+
+            shell("service-sas","service-sas-biz");
+    }
+
+    private static void shell(String parentName,String model) {
+
+        AutoGenerator mpg = new AutoGenerator();
+        //1、全局配置
+        GlobalConfig gc = new GlobalConfig();
+//        File file = new File(model);
+//        String path = file.getAbsolutePath();
+        String projectPath = System.getProperty("user.dir");
+        projectPath+="/"+parentName;
+        projectPath+="/"+model;
+        gc.setOutputDir(projectPath+ "/src/main/java");  //生成路径(一般都是生成在此项目的src/main/java下面)
+        //修改为自己的名字
+        gc.setAuthor("fu"); //设置作者
+        gc.setOpen(false);
+        gc.setFileOverride(true); //第二次生成会把第一次生成的覆盖掉
+        gc.setServiceName("%sService"); //生成的service接口名字首字母是否为I,这样设置就没有
+        gc.setBaseResultMap(true); //生成resultMap
+        mpg.setGlobalConfig(gc);
+
+        //2、数据源配置
+        //修改数据源
+        DataSourceConfig dsc = new DataSourceConfig();
+        dsc.setUrl("jdbc:mysql://192.168.10.165:3306/usky-cloud?useUnicode=true&serverTimezone=GMT&useSSL=false&characterEncoding=utf8");
+        dsc.setDriverName("com.mysql.jdbc.Driver");
+        dsc.setUsername("root");
+        dsc.setPassword("yt123456");
+        mpg.setDataSource(dsc);
+
+        // 3、包配置
+        PackageConfig pc = new PackageConfig();
+        pc.setParent("com.usky.sas");
+        pc.setController("controller.web");
+        pc.setEntity("domain");
+        pc.setMapper("mapper");
+        pc.setService("service");
+        pc.setServiceImpl("service.impl");
+//        pc.setXml("mapper.demo");
+        //pc.setModuleName("test");
+        mpg.setPackageInfo(pc);
+
+        // 4、策略配置
+        StrategyConfig strategy = new StrategyConfig();
+        strategy.setNaming(NamingStrategy.underline_to_camel);
+        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
+        strategy.setSuperMapperClass("com.usky.common.mybatis.core.CrudMapper");
+        strategy.setSuperServiceClass("com.usky.common.mybatis.core.CrudService");
+        strategy.setSuperServiceImplClass("com.usky.common.mybatis.core.AbstractCrudService");
+        // strategy.setTablePrefix("t_"); // 表名前缀
+        strategy.setEntityLombokModel(true); //使用lombok
+        //修改自己想要生成的表
+        strategy.setInclude("sas_snap_type_code");  // 逆向工程使用的表   如果要生成多个,这里可以传入String[]
+        mpg.setStrategy(strategy);
+
+        // 关闭默认 xml 生成,调整生成 至 根目录
+        //修改对应的模块名称
+        TemplateConfig tc = new TemplateConfig();
+        // 自定义配置
+        InjectionConfig cfg = new InjectionConfig() {
+            @Override
+            public void initMap() {
+                // to do nothing
+            }
+        };
+        //如果模板引擎是 velocity
+        String templatePath = "/templates/mapper.xml.vm";
+        // 自定义输出配置
+        List<FileOutConfig> focList = new ArrayList<>();
+        // 自定义配置会被优先输出
+        String finalProjectPath = projectPath;
+        focList.add(new FileOutConfig(templatePath) {
+            @Override
+            public String outputFile(TableInfo tableInfo) {
+                // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
+                return finalProjectPath + "/src/main/resources/mapper/sas" + "/"
+                        + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
+            }
+        });
+        cfg.setFileOutConfigList(focList);
+        mpg.setCfg(cfg);
+        tc.setXml(null);
+        mpg.setTemplate(tc);
+        //5、执行
+        mpg.execute();
+    }
+}

+ 64 - 9
service-sas/service-sas-biz/src/main/java/com/usky/sas/controller/web/SasHomepageController.java

@@ -3,13 +3,15 @@ package com.usky.sas.controller.web;
 import com.usky.common.core.bean.ApiResult;
 import com.usky.common.core.bean.CommonPage;
 import com.usky.sas.service.SasHomepageService;
-import com.usky.sas.service.vo.HomepageAlertHistoryRequest;
-import com.usky.sas.service.vo.HomepageInfoResponse;
-import com.usky.sas.service.vo.IntelligentEventItem;
-import com.usky.sas.service.vo.IntelligentEventPageRequest;
+import com.usky.sas.service.vo.*;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.List;
@@ -20,6 +22,7 @@ import java.util.List;
  * 对应 API 文档:/prod-api/service-sas/homepage/...
  * 功能:左上角摄像头列表与直播、左下角服务器信息、中上事件列表与实时事件、中下预警历史
  */
+@Api(tags = "首页管理")
 @RestController
 @RequestMapping("/homepage")
 public class SasHomepageController {
@@ -30,22 +33,25 @@ public class SasHomepageController {
     /**
      * 1. 查询首页综合信息(摄像头列表、统计、服务器资源使用情况)
      */
+    @ApiOperation("查询首页综合信息")
     @GetMapping("/info")
-    public ApiResult<HomepageInfoResponse> getInfo() {
-        return ApiResult.success(sasHomepageService.getHomepageInfo());
+    public ApiResult<HomepageInfoResponse> getInfo(@RequestParam(value = "ipAddr",required = false) String ipAddr) {
+        return ApiResult.success(sasHomepageService.getHomepageInfo(ipAddr));
     }
 
     /**
      * 2. 事件列表:各模块所有事件分页(中上-事件列表区域)
      */
+    @ApiOperation("查询事件列表")
     @GetMapping("/events")
-    public ApiResult<CommonPage<IntelligentEventItem>> getEventList(IntelligentEventPageRequest request) {
+    public ApiResult<CommonPage<IntelligentEventItem>> getEventList(@Validated IntelligentEventPageRequest request) {
         return ApiResult.success(sasHomepageService.getEventList(request));
     }
 
     /**
      * 3. 实时事件:开启通知的最近事件,用于弹窗(左边关联摄像头、右边事件信息,可提前关闭)
      */
+    @ApiOperation("查询实时通知事件")
     @GetMapping("/realtimeNotificationEvents")
     public ApiResult<List<IntelligentEventItem>> getRealtimeNotificationEvents() {
         return ApiResult.success(sasHomepageService.getRealtimeNotificationEvents());
@@ -54,9 +60,58 @@ public class SasHomepageController {
     /**
      * 4. 预警历史:按分类显示开启通知的事件预警历史,可分页、点详情
      */
+    @ApiOperation("查询预警历史")
     @GetMapping("/alertHistory")
-    public ApiResult<CommonPage<IntelligentEventItem>> getAlertHistory(HomepageAlertHistoryRequest request) {
+    public ApiResult<CommonPage<IntelligentEventItem>> getAlertHistory(@Validated HomepageAlertHistoryRequest request) {
         return ApiResult.success(sasHomepageService.getAlertHistory(request));
     }
-}
 
+    /**
+     * 5. 系统资源信息:CPU、内存、磁盘、Agbox/MetaBus状态(左下角系统信息模块)
+     */
+    @ApiOperation("查询系统资源信息")
+    @GetMapping("/systemResource")
+    public ApiResult<SystemResourceResponse> getSystemResource() {
+        return ApiResult.success(sasHomepageService.getSystemResource());
+    }
+
+    /**
+     * 6. 事件详情:根据事件类型和事件ID查询事件详细信息
+     */
+    @ApiOperation("查询事件详情")
+    @GetMapping("/eventDetail")
+    public ApiResult<EventDetailResponse> getEventDetail(
+            @ApiParam(value = "事件类型", required = true, example = "snap") 
+            @RequestParam String eventType,
+            @ApiParam(value = "事件ID", required = true, example = "123456") 
+            @RequestParam String eventId) {
+        return ApiResult.success(sasHomepageService.getEventDetail(eventType, eventId));
+    }
+
+    /**
+     * 7. 实时视频流
+     */
+    @ApiOperation("获取实时视频流")
+    @GetMapping("/videoStream")
+    public ApiResult<String> getUnityVideoStream(
+            @ApiParam(value = "设备ID") @RequestParam(required = false) String id,
+            @ApiParam(value = "设备编号") @RequestParam(required = false) String deviceId,
+            @ApiParam(value = "通道号") @RequestParam(required = false) Integer channel,
+            @ApiParam(value = "设备类型") @RequestParam(required = false) Integer deviceType) {
+        return ApiResult.success(sasHomepageService.getUnityVideoStream(id, deviceId, channel, deviceType));
+    }
+
+//    /**
+//     * 8. 回放视频流
+//     */
+//    @ApiOperation("获取回放视频流")
+//    @GetMapping("/videoBackStream")
+//    public ApiResult<VideoStreamVo> getUnityVideoBackStream(
+//            @ApiParam(value = "设备ID") @RequestParam(required = false) String id,
+//            @ApiParam(value = "开始时间") @RequestParam String beginTime,
+//            @ApiParam(value = "结束时间") @RequestParam String endTime,
+//            @ApiParam(value = "句柄") @RequestParam(required = false) Integer handle,
+//            @ApiParam(value = "旧Mac地址") @RequestParam(required = false) String oldMac) {
+//        return ApiResult.success(sasHomepageService.getUnityVideoBackStream(id, beginTime, endTime, handle, oldMac));
+//    }
+}

+ 24 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasCarTypeCode.java

@@ -0,0 +1,24 @@
+package com.usky.sas.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * 车辆类型编码表
+ */
+@Data
+@TableName("sas_car_type_code")
+public class SasCarTypeCode {
+
+    /**
+     * 主键
+     */
+    @TableId
+    private Integer code;
+
+    /**
+     * 名称
+     */
+    private String name;
+}

+ 24 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasCertifiedTypeCode.java

@@ -0,0 +1,24 @@
+package com.usky.sas.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * 认证类型编码表
+ */
+@Data
+@TableName("sas_certified_type_code")
+public class SasCertifiedTypeCode {
+
+    /**
+     * 主键
+     */
+    @TableId
+    private Integer code;
+
+    /**
+     * 名称
+     */
+    private String name;
+}

+ 1 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasEntranceEventCode.java

@@ -15,5 +15,6 @@ public class SasEntranceEventCode implements Serializable {
     private static final long serialVersionUID = 1L;
     @TableId(value = "code")
     private Integer code;
+
     private String name;
 }

+ 1 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasPatrolEventCode.java

@@ -15,5 +15,6 @@ public class SasPatrolEventCode implements Serializable {
     private static final long serialVersionUID = 1L;
     @TableId(value = "code")
     private Integer code;
+
     private String name;
 }

+ 1 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasPerceptionEventCode.java

@@ -15,5 +15,6 @@ public class SasPerceptionEventCode implements Serializable {
     private static final long serialVersionUID = 1L;
     @TableId(value = "code")
     private Integer code;
+
     private String name;
 }

+ 25 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasPersonTypeCode.java

@@ -0,0 +1,25 @@
+package com.usky.sas.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+/**
+ * 人员类型编码表
+ * 别名类,映射到 sas_people_type_code 表
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("sas_people_type_code")
+public class SasPersonTypeCode implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "code")
+    private Integer code;
+
+    private String name;
+}

+ 39 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasPic.java

@@ -0,0 +1,39 @@
+package com.usky.sas.domain;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 图片文件地址表
+ */
+@Data
+@TableName("sas_pic")
+public class SasPic {
+
+    /**
+     * 主键id
+     */
+    private String id;
+
+    /**
+     * 图片地址
+     */
+    private String url;
+
+    /**
+     * 图片路径
+     */
+    private String path;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+}

+ 24 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasPlateColor.java

@@ -0,0 +1,24 @@
+package com.usky.sas.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * 车牌颜色分类表
+ */
+@Data
+@TableName("sas_plate_color")
+public class SasPlateColor {
+
+    /**
+     * 主键编码
+     */
+    @TableId
+    private String code;
+
+    /**
+     * 名称
+     */
+    private String name;
+}

+ 24 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasPlateTypeCode.java

@@ -0,0 +1,24 @@
+package com.usky.sas.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * 车辆牌照类型编码表
+ */
+@Data
+@TableName("sas_plate_type_code")
+public class SasPlateTypeCode {
+
+    /**
+     * 主键
+     */
+    @TableId
+    private Integer code;
+
+    /**
+     * 名称
+     */
+    private String name;
+}

+ 1 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasSnapTypeCode.java

@@ -18,4 +18,5 @@ public class SasSnapTypeCode implements Serializable {
     private String name;
     /** 1:启用 0:未启用 */
     private Integer isUsed;
+
 }

+ 7 - 9
service-sas/service-sas-biz/src/main/java/com/usky/sas/domain/SasSystemConfig.java

@@ -4,22 +4,20 @@ import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
-import lombok.EqualsAndHashCode;
 
-import java.io.Serializable;
 import java.time.LocalDateTime;
 
 /**
  * 系统配置表
  */
 @Data
-@EqualsAndHashCode(callSuper = false)
 @TableName("sas_system_config")
-public class SasSystemConfig implements Serializable {
+public class SasSystemConfig {
 
-    private static final long serialVersionUID = 1L;
-
-    @TableId(value = "id", type = IdType.AUTO)
+    /**
+     * 主键id
+     */
+    @TableId(type = IdType.AUTO)
     private Integer id;
 
     /**
@@ -48,12 +46,12 @@ public class SasSystemConfig implements Serializable {
     private Integer daysToKeepHistory;
 
     /**
-     * 是否显示人员照片
+     * 是否显示人员照片 true:显示,false:不显示
      */
     private Boolean maskAvatar;
 
     /**
-     * 是否显示身份证信息
+     * 是否显示身份证信息 true:显示,false:不显示
      */
     private Boolean maskIdCardNo;
 

+ 10 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasCarTypeCodeMapper.java

@@ -0,0 +1,10 @@
+package com.usky.sas.mapper;
+
+import com.usky.common.mybatis.core.CrudMapper;
+import com.usky.sas.domain.SasCarTypeCode;
+
+/**
+ * 车辆类型编码表 Mapper 接口
+ */
+public interface SasCarTypeCodeMapper extends CrudMapper<SasCarTypeCode> {
+}

+ 10 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasCertifiedTypeCodeMapper.java

@@ -0,0 +1,10 @@
+package com.usky.sas.mapper;
+
+import com.usky.common.mybatis.core.CrudMapper;
+import com.usky.sas.domain.SasCertifiedTypeCode;
+
+/**
+ * 认证类型编码表 Mapper 接口
+ */
+public interface SasCertifiedTypeCodeMapper extends CrudMapper<SasCertifiedTypeCode> {
+}

+ 3 - 8
service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasGisMapper.java

@@ -2,17 +2,12 @@ package com.usky.sas.mapper;
 
 import com.usky.common.mybatis.core.CrudMapper;
 import com.usky.sas.domain.SasGis;
-import org.apache.ibatis.annotations.Param;
 
-import java.util.List;
+import java.util.ArrayList;
 
 /**
- * 经纬度信息 Mapper 接口
+ * 经纬度信息 Mapper 接口
  */
 public interface SasGisMapper extends CrudMapper<SasGis> {
-
-    /**
-     * 根据 id 列表批量查询
-     */
-    List<SasGis> selectByIds(@Param("ids") List<String> ids);
+    Object selectByIds(ArrayList<String> strings);
 }

+ 10 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasPersonTypeCodeMapper.java

@@ -0,0 +1,10 @@
+package com.usky.sas.mapper;
+
+import com.usky.common.mybatis.core.CrudMapper;
+import com.usky.sas.domain.SasPersonTypeCode;
+
+/**
+ * 人员类型编码 Mapper 接口
+ */
+public interface SasPersonTypeCodeMapper extends CrudMapper<SasPersonTypeCode> {
+}

+ 10 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasPicMapper.java

@@ -0,0 +1,10 @@
+package com.usky.sas.mapper;
+
+import com.usky.common.mybatis.core.CrudMapper;
+import com.usky.sas.domain.SasPic;
+
+/**
+ * 图片文件地址表 Mapper 接口
+ */
+public interface SasPicMapper extends CrudMapper<SasPic> {
+}

+ 10 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasPlateColorMapper.java

@@ -0,0 +1,10 @@
+package com.usky.sas.mapper;
+
+import com.usky.common.mybatis.core.CrudMapper;
+import com.usky.sas.domain.SasPlateColor;
+
+/**
+ * 车牌颜色分类表 Mapper 接口
+ */
+public interface SasPlateColorMapper extends CrudMapper<SasPlateColor> {
+}

+ 10 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasPlateTypeCodeMapper.java

@@ -0,0 +1,10 @@
+package com.usky.sas.mapper;
+
+import com.usky.common.mybatis.core.CrudMapper;
+import com.usky.sas.domain.SasPlateTypeCode;
+
+/**
+ * 车辆牌照类型编码表 Mapper 接口
+ */
+public interface SasPlateTypeCodeMapper extends CrudMapper<SasPlateTypeCode> {
+}

+ 1 - 1
service-sas/service-sas-biz/src/main/java/com/usky/sas/mapper/SasSystemConfigMapper.java

@@ -4,7 +4,7 @@ import com.usky.common.mybatis.core.CrudMapper;
 import com.usky.sas.domain.SasSystemConfig;
 
 /**
- * 系统配置 Mapper 接口
+ * 系统配置 Mapper 接口
  */
 public interface SasSystemConfigMapper extends CrudMapper<SasSystemConfig> {
 }

+ 22 - 6
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/SasHomepageService.java

@@ -1,10 +1,7 @@
 package com.usky.sas.service;
 
 import com.usky.common.core.bean.CommonPage;
-import com.usky.sas.service.vo.HomepageAlertHistoryRequest;
-import com.usky.sas.service.vo.HomepageInfoResponse;
-import com.usky.sas.service.vo.IntelligentEventItem;
-import com.usky.sas.service.vo.IntelligentEventPageRequest;
+import com.usky.sas.service.vo.*;
 
 import java.util.List;
 
@@ -13,7 +10,7 @@ public interface SasHomepageService {
     /**
      * 首页综合信息:摄像头列表、统计、服务器信息
      */
-    HomepageInfoResponse getHomepageInfo();
+    HomepageInfoResponse getHomepageInfo(String var1);
 
     /**
      * 事件列表:各模块所有事件分页(实时监控/事件列表区域)
@@ -29,5 +26,24 @@ public interface SasHomepageService {
      * 预警历史:按分类显示开启通知的事件预警历史,可分页、点详情
      */
     CommonPage<IntelligentEventItem> getAlertHistory(HomepageAlertHistoryRequest request);
-}
 
+    /**
+     * 系统资源信息:CPU、内存、磁盘、Agbox/MetaBus状态
+     */
+    SystemResourceResponse getSystemResource();
+
+    /**
+     * 事件详情:根据事件类型和事件ID查询事件详细信息
+     */
+    EventDetailResponse getEventDetail(String eventType, String eventId);
+
+    /**
+     * 实时视频流
+     */
+    String getUnityVideoStream(String id, String deviceId, Integer channel, Integer deviceType);
+
+    /**
+     * 回放视频流
+     */
+//    VideoStreamVo getUnityVideoBackStream(String id, String beginTime, String endTime, Integer handle, String oldMac);
+}

+ 12 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/SasIntelligentService.java

@@ -1,6 +1,7 @@
 package com.usky.sas.service;
 
 import com.usky.common.core.bean.CommonPage;
+import com.usky.sas.service.vo.EventDetailResponse;
 import com.usky.sas.service.vo.IntelligentEventItem;
 import com.usky.sas.service.vo.IntelligentEventPageRequest;
 
@@ -17,5 +18,16 @@ public interface SasIntelligentService {
     CommonPage<IntelligentEventItem> queryParking(IntelligentEventPageRequest request);
 
     CommonPage<IntelligentEventItem> queryPatrol(IntelligentEventPageRequest request);
+
+    CommonPage<IntelligentEventItem> queryUsb(IntelligentEventPageRequest request);
+
+    CommonPage<IntelligentEventItem> queryPerception(IntelligentEventPageRequest request);
+
+    CommonPage<IntelligentEventItem> queryAcquisition(IntelligentEventPageRequest request);
+
+    CommonPage<IntelligentEventItem> queryCollection(IntelligentEventPageRequest request);
+
+    CommonPage<IntelligentEventItem> queryRoadblock(IntelligentEventPageRequest request);
+
 }
 

+ 807 - 33
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/impl/SasHomepageServiceImpl.java

@@ -1,35 +1,85 @@
 package com.usky.sas.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.IdcardUtil;
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.usky.common.core.bean.CommonPage;
-import com.usky.sas.domain.SasCollectionEvent;
-import com.usky.sas.domain.SasDevice;
-import com.usky.sas.domain.SasSnapEvent;
-import com.usky.sas.mapper.SasCollectionEventMapper;
-import com.usky.sas.mapper.SasDeviceMapper;
-import com.usky.sas.mapper.SasSnapEventMapper;
+import com.usky.sas.common.UnityVideoInfo;
+import com.usky.sas.common.enums.ProtocolEnum;
+import com.usky.sas.common.enums.SystemTypeCodeEnum;
+import com.usky.sas.common.exception.BusinessException;
+import com.usky.sas.common.util.ZLMediaKitUtils;
+import com.usky.sas.common.dahua.DahuaVideoStreamService;
+import com.usky.sas.common.entity.DeviceVideoInfo;
+import com.usky.sas.common.entity.DahuaNvrInfo;
+import com.usky.sas.common.enums.DeviceTypeEnum;
+import com.usky.sas.mqtt.MqttService;
+//import com.usky.sas.common.hik.HCNetSDK;
+//import com.usky.sas.common.hik.InitHCNetSDK;
+//import com.usky.sas.common.hik.VideoResolutionUtils;
+//import com.usky.sas.common.hik.HikVideoStreamService;
+//import com.usky.sas.common.dahua.InitNetSDKLib;
+import com.usky.sas.common.util.GetIpUtils;
+import com.usky.sas.common.StandardOnvifService;
+import com.usky.sas.domain.*;
+import com.usky.sas.mapper.*;
+import com.usky.sas.mqtt.MqttService;
 import com.usky.sas.service.SasHomepageService;
 import com.usky.sas.service.SasIntelligentService;
-import com.usky.sas.service.vo.HomepageInfoResponse;
+import com.usky.sas.service.vo.EventDetailResponse;
 import com.usky.sas.service.vo.HomepageAlertHistoryRequest;
+import com.usky.sas.service.vo.HomepageInfoResponse;
 import com.usky.sas.service.vo.IntelligentEventItem;
 import com.usky.sas.service.vo.IntelligentEventPageRequest;
+import com.usky.sas.service.vo.SystemResourceResponse;
+import com.usky.sas.service.vo.VideoStreamVo;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
+import java.io.File;
+import java.text.DecimalFormat;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
-import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
 
 @Service
 public class SasHomepageServiceImpl implements SasHomepageService {
 
+    @Autowired
+    private ZLMediaKitUtils zlMediaKitUtils;
+
+    @Value("${media-kit.port:10000}")
+    private Integer mediaPort;
+
+    @Value("${media-kit.http.port:80}")
+    private Integer mediaHttpPort;
+
+    @Value("${media-kit.secret:secret}")
+    private String mediaKitSecret;
+
+    private Map<String, UnityVideoInfo> unityVideoInfo = new ConcurrentHashMap<>();
+    private Map<String, DeviceVideoInfo> hikVideoInfo = new ConcurrentHashMap<>();
+    private Map<String, Integer> loginHikNvrUser = new ConcurrentHashMap<>();
+    private Map<String, DahuaNvrInfo> dhNvrUser = new ConcurrentHashMap<>();
+
+    private long globalSsrc = 0;
+
+    @Autowired
+    private StandardOnvifService standardOnvifService;
+
     @Autowired
     private SasDeviceMapper sasDeviceMapper;
 
@@ -42,9 +92,96 @@ public class SasHomepageServiceImpl implements SasHomepageService {
     @Autowired
     private SasIntelligentService sasIntelligentService;
 
+    @Autowired
+    private SasConfigMapper sasConfigMapper;
+
+    @Autowired
+    private SasUsbEventMapper sasUsbEventMapper;
+
+    @Autowired
+    private SasEntranceEventMapper sasEntranceEventMapper;
+
+    @Autowired
+    private SasParkingEventMapper sasParkingEventMapper;
+
+    @Autowired
+    private SasAlarsasEventMapper sasAlarsasEventMapper;
+
+    @Autowired
+    private SasPatrolEventMapper sasPatrolEventMapper;
+
+    @Autowired
+    private SasPerceptionEventMapper sasPerceptionEventMapper;
+
+    @Autowired
+    private SasAcquisitionEventMapper sasAcquisitionEventMapper;
+
+    @Autowired
+    private SasRoadblockEventMapper sasRoadblockEventMapper;
+
+    @Autowired
+    private SasPersonMapper sasPersonMapper;
+
+    @Autowired
+    private SasCredentialTypeCodeMapper sasCredentialTypeCodeMapper;
+
+    @Autowired
+    private SasSystemConfigMapper sasSystemConfigMapper;
+
+    @Autowired
+    private SasGisMapper sasGisMapper;
+
+    @Autowired
+    private SasPicMapper sasPicMapper;
+
+    @Autowired
+    private SasSnapTypeCodeMapper sasSnapTypeCodeMapper;
+
+    @Autowired
+    private SasUsbEventCodeMapper sasUsbEventCodeMapper;
+
+    @Autowired
+    private SasEntranceEventCodeMapper sasEntranceEventCodeMapper;
+
+    @Autowired
+    private SasPeopleTypeCodeMapper sasPeopleTypeCodeMapper;
+
+    @Autowired
+    private SasCarTypeCodeMapper sasCarTypeCodeMapper;
+
+    @Autowired
+    private SasPlateTypeCodeMapper sasPlateTypeCodeMapper;
+
+    @Autowired
+    private SasParkingEventCodeMapper sasParkingEventCodeMapper;
+
+    @Autowired
+    private SasPlateColorMapper sasPlateColorMapper;
+
+    @Autowired
+    private SasAlarsasEventCodeMapper sasAlarsasEventCodeMapper;
+
+    @Autowired
+    private SasPatrolEventCodeMapper sasPatrolEventCodeMapper;
+
+    @Autowired
+    private SasPerceptionEventCodeMapper sasPerceptionEventCodeMapper;
+
+    @Autowired
+    private SasAcquisitionEventCodeMapper sasAcquisitionEventCodeMapper;
+
+    @Autowired
+    private SasCollectionEventCodeMapper sasCollectionEventCodeMapper;
+
+    @Autowired
+    private SasRoadblockEventCodeMapper sasRoadblockEventCodeMapper;
+
+    @Autowired
+    private MqttService mqttService;
+
     @Override
-    public HomepageInfoResponse getHomepageInfo() {
-        List<SasDevice> devices = sasDeviceMapper.selectList(Wrappers.lambdaQuery());
+    public HomepageInfoResponse getHomepageInfo(String ipAddr) {
+        List<SasDevice> devices = sasDeviceMapper.selectList(new LambdaQueryWrapper<SasDevice>().eq(SasDevice::getDeviceType, SystemTypeCodeEnum.video.getCode()).like(StrUtil.isNotBlank(ipAddr), SasDevice::getIpAddr, ipAddr));
 
         HomepageInfoResponse resp = new HomepageInfoResponse();
         resp.setCameras(devices.stream().map(this::toCameraItem).collect(Collectors.toList()));
@@ -55,36 +192,604 @@ public class SasHomepageServiceImpl implements SasHomepageService {
 
         LocalDateTime startOfDay = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
         LocalDateTime endOfDay = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
+
         LambdaQueryWrapper<SasCollectionEvent> wrapper = Wrappers.lambdaQuery();
         wrapper.between(SasCollectionEvent::getTriggerTime, startOfDay, endOfDay);
+
         long todayEvents = sasCollectionEventMapper.selectCount(wrapper);
         stat.setTodayEvents(todayEvents);
-
         // 暂无单独报警事件表,这里先与今日事件数保持一致
         stat.setAlarmEvents(todayEvents);
 
         resp.setStatistics(stat);
+        return resp;
+    }
 
-        // 左下角:服务器信息与资源使用情况
-        resp.setServerInfo(buildServerInfo());
+    private String toHexString(long ssrc) {
+        return Long.toHexString(ssrc);
+    }
 
-        return resp;
+    @Override
+    public String getUnityVideoStream(String id, String deviceId, Integer channel, Integer deviceType) {
+        SasDevice device = null;
+        if (StrUtil.isNotBlank(id)) {
+            device = sasDeviceMapper.selectById(id);
+        } else {
+            LambdaQueryWrapper<SasDevice> wrapper = new LambdaQueryWrapper<>();
+            wrapper.eq(SasDevice::getDeviceId, deviceId);
+            if (channel != null) {
+                wrapper.eq(SasDevice::getChannel, channel);
+            }
+            if (deviceType != null) {
+                wrapper.eq(SasDevice::getDeviceType, deviceType);
+            }
+            
+            SasDevice eventDevice = sasDeviceMapper.selectOne(wrapper);
+            if (eventDevice != null) {
+                if (StrUtil.isNotBlank(eventDevice.getBindingIpc())) {
+                    device = sasDeviceMapper.selectById(eventDevice.getBindingIpc());
+                } else if (StrUtil.isNotBlank(eventDevice.getAlarsasGroupType())) {
+                    List<SasDevice> deviceList = sasDeviceMapper.selectList(new LambdaQueryWrapper<SasDevice>()
+                            .eq(SasDevice::getAlarsasGroupType, eventDevice.getAlarsasGroupType())
+                            .eq(SasDevice::getDeviceType, SystemTypeCodeEnum.video.getCode()));
+                    if (CollUtil.isNotEmpty(deviceList)) {
+                        device = deviceList.get(0);
+                    }
+                }
+            }
+        }
+
+        if (device == null) {
+            return null;
+        } else {
+            Integer protocol = device.getVideoProtocol();
+            if (protocol.equals(ProtocolEnum.ONVIF.getCode())) {
+                UnityVideoInfo info = null;
+                info = (UnityVideoInfo)this.unityVideoInfo.get(device.getDeviceId() + device.getDeviceType() + device.getChannel());
+                if (info != null) {
+                    boolean isExist = this.zlMediaKitUtils.streamIsExist(GetIpUtils.getServerIP(), this.mediaHttpPort, this.mediaKitSecret, info.getSsrc());
+                    if (isExist) {
+                        return info.getUrl();
+                    }
+                }
+
+                String rtspUri = null;
+                if (device.getVideoType().equals(DeviceTypeEnum.NVR.getCode())) {
+                    rtspUri = this.standardOnvifService.getNvrRealTimeStreamUrl(device.getIpAddr(), device.getUsername(), device.getPassword(), device.getVideoSourceToken());
+                } else {
+                    rtspUri = this.standardOnvifService.getRealTimeStreamUrl(device.getIpAddr(), device.getUsername(), device.getPassword());
+                }
+
+                this.globalSsrc = this.globalSsrc >= 4294967295L ? 65535L : this.globalSsrc + 1L;
+                String key = this.zlMediaKitUtils.addStreamProxy(this.mediaKitSecret, toHexString(this.globalSsrc), rtspUri, device.getUsername(), device.getPassword());
+                UnityVideoInfo onvifVideoInfo = new UnityVideoInfo();
+                onvifVideoInfo.setMacAddr(device.getDeviceId() + device.getChannel() + device.getDeviceType());
+                onvifVideoInfo.setKey(key);
+                onvifVideoInfo.setSsrc(toHexString(this.globalSsrc));
+                onvifVideoInfo.setUrl("http://" + GetIpUtils.getServerIP() + ":" + this.mediaHttpPort + "/index/api/webrtc?app=rtp&stream=" + toHexString(this.globalSsrc) + "&type=play");
+                this.unityVideoInfo.put(device.getDeviceId() + device.getChannel() + device.getDeviceType(), onvifVideoInfo);
+                return "http://" + GetIpUtils.getServerIP() + ":" + this.mediaHttpPort + "/index/api/webrtc?app=rtp&stream=" + toHexString(this.globalSsrc) + "&type=play";
+            } else if (protocol.equals(ProtocolEnum.HIK.getCode())) {
+                UnityVideoInfo info = null;
+                info = (UnityVideoInfo)this.unityVideoInfo.get(device.getDeviceId() + device.getDeviceType() + device.getChannel());
+                if (info != null) {
+                    boolean isExist = this.zlMediaKitUtils.streamIsExist(GetIpUtils.getServerIP(), this.mediaHttpPort, this.mediaKitSecret, info.getSsrc());
+                    if (isExist) {
+                        return info.getUrl();
+                    }
+                }
+
+                this.globalSsrc = this.globalSsrc >= 4294967295L ? 65535L : this.globalSsrc + 1L;
+                String rtspUrl = null;
+                if (DeviceTypeEnum.IPC.getCode().equals(device.getDeviceType())) {
+                    rtspUrl = String.format("rtsp://%s:%s@%s:554/Streaming/Channels/%d", device.getUsername(), device.getPassword(), device.getIpAddr(), device.getChannel());
+                } else {
+                    rtspUrl = String.format("rtsp://%s:%s@%s:554/Streaming/Channels/%d", device.getUsername(), device.getPassword(), device.getIpAddr(), device.getChannel() * 100 + 1);
+                }
+
+                String key = this.zlMediaKitUtils.addStreamUnityProxy(this.mediaKitSecret, toHexString(this.globalSsrc), rtspUrl);
+                UnityVideoInfo hikVideoInfo = new UnityVideoInfo();
+                hikVideoInfo.setUrl("http://" + GetIpUtils.getServerIP() + ":" + this.mediaHttpPort + "/index/api/webrtc?app=rtp&stream=" + toHexString(this.globalSsrc) + "&type=play");
+                hikVideoInfo.setSsrc(toHexString(this.globalSsrc));
+                hikVideoInfo.setMacAddr(device.getDeviceId() + device.getDeviceType() + device.getChannel());
+                hikVideoInfo.setKey(key);
+                this.unityVideoInfo.put(device.getDeviceId() + device.getDeviceType() + device.getChannel(), hikVideoInfo);
+                return "http://" + GetIpUtils.getServerIP() + ":" + this.mediaHttpPort + "/index/api/webrtc?app=rtp&stream=" + toHexString(this.globalSsrc) + "&type=play";
+            } else if (protocol.equals(ProtocolEnum.DA_HUA.getCode())) {
+                UnityVideoInfo info = null;
+                info = (UnityVideoInfo)this.unityVideoInfo.get(device.getDeviceId() + device.getDeviceType() + device.getChannel());
+                if (info != null) {
+                    boolean isExist = this.zlMediaKitUtils.streamIsExist(GetIpUtils.getServerIP(), this.mediaHttpPort, this.mediaKitSecret, info.getSsrc());
+                    if (isExist) {
+                        return info.getUrl();
+                    }
+                }
+
+                this.globalSsrc = this.globalSsrc >= 4294967295L ? 65535L : this.globalSsrc + 1L;
+                String rtspUrl = String.format("rtsp://%s:%s@%s:554/cam/realmonitor?channel=%d&subtype=0", device.getUsername(), device.getPassword(), device.getIpAddr(), device.getChannel());
+                String key = this.zlMediaKitUtils.addStreamUnityProxy(this.mediaKitSecret, toHexString(this.globalSsrc), rtspUrl);
+                UnityVideoInfo dahuaVideoInfo = new UnityVideoInfo();
+                dahuaVideoInfo.setUrl("http://" + GetIpUtils.getServerIP() + ":" + this.mediaHttpPort + "/index/api/webrtc?app=rtp&stream=" + toHexString(this.globalSsrc) + "&type=play");
+                dahuaVideoInfo.setSsrc(toHexString(this.globalSsrc));
+                dahuaVideoInfo.setMacAddr(device.getDeviceId() + device.getDeviceType() + device.getChannel());
+                dahuaVideoInfo.setKey(key);
+                this.unityVideoInfo.put(device.getDeviceId() + device.getDeviceType() + device.getChannel(), dahuaVideoInfo);
+                return "http://" + GetIpUtils.getServerIP() + ":" + this.mediaHttpPort + "/index/api/webrtc?app=rtp&stream=" + toHexString(this.globalSsrc) + "&type=play";
+            } else {
+                return null;
+            }
+        }
     }
 
-    private HomepageInfoResponse.ServerInfo buildServerInfo() {
-        Runtime runtime = Runtime.getRuntime();
-        long maxMemory = runtime.maxMemory();
-        long totalMemory = runtime.totalMemory();
-        long freeMemory = runtime.freeMemory();
-        long usedMemory = totalMemory - freeMemory;
+//    @Override
+//    public VideoStreamVo getUnityVideoBackStream(String id, String beginTime, String endTime, Integer handle, String oldMac) {
+//        Date begin = DateUtil.parse(beginTime, "yyyy-MM-dd HH:mm:ss");
+//        Date end = DateUtil.parse(endTime, "yyyy-MM-dd HH:mm:ss");
+//        VideoStreamVo streamVo = null;
+//        SasDevice device = null;
+//        if (StrUtil.isNotBlank(id)) {
+//            device = sasDeviceMapper.selectById(id);
+//        }
+//
+//        if (device == null) {
+//            return null;
+//        } else if (device.getVideoProtocol().equals(ProtocolEnum.ONVIF.getCode())) {
+//            return null;
+//        } else {
+//            if (device.getVideoProtocol().equals(ProtocolEnum.HIK.getCode())) {
+//                Integer userId = null;
+//                int bitrate = 0;
+//                DeviceVideoInfo deviceVideoInfo = (DeviceVideoInfo)this.hikVideoInfo.get(device.getDeviceId() + device.getDeviceType() + device.getChannel());
+//                if (deviceVideoInfo != null) {
+//                    userId = deviceVideoInfo.getUserId();
+//                } else if (device.getVideoType().equals(DeviceTypeEnum.NVR.getCode())) {
+//                    userId = InitHCNetSDK.loginDevice(device.getRemoteIpcIpAddr(), device.getPort().shortValue(), device.getUsername(), device.getPassword());
+//                    HCNetSDK.NET_DVR_MULTI_STREAM_COMPRESSIONCFG config = VideoResolutionUtils.getCompressionConfig(userId, 1, 0);
+//                    bitrate = config.struStreamPara.dwVideoBitrate;
+//                } else {
+//                    userId = InitHCNetSDK.loginDevice(device.getIpAddr(), device.getPort().shortValue(), device.getUsername(), device.getPassword());
+//                    HCNetSDK.NET_DVR_MULTI_STREAM_COMPRESSIONCFG config = VideoResolutionUtils.getCompressionConfig(userId, device.getChannel(), 0);
+//                    bitrate = config.struStreamPara.dwVideoBitrate;
+//                }
+//
+//                List<SasDevice> nvrDevices = sasDeviceMapper.selectList(new LambdaQueryWrapper<SasDevice>().eq(SasDevice::getVideoType, DeviceTypeEnum.NVR.getCode()));
+//                Integer channel = null;
+//                Integer loginNvr = null;
+//                String macAddr = null;
+//                if (CollUtil.isNotEmpty(nvrDevices)) {
+//                    List<SasDevice> collect = nvrDevices.stream().filter((device1) -> this.loginHikNvrUser.containsKey(device1.getDeviceId() + device1.getDeviceType() + device1.getChannel())).collect(Collectors.toList());
+//                    if (CollUtil.isNotEmpty(collect)) {
+//                        for(SasDevice d : collect) {
+//                            macAddr = d.getDeviceId() + d.getDeviceType() + d.getChannel();
+//                            loginNvr = (Integer)this.loginHikNvrUser.get(macAddr);
+//                            if (device.getVideoType().equals(DeviceTypeEnum.NVR.getCode())) {
+//                                channel = InitHCNetSDK.getIPChannelInfo(loginNvr, device.getRemoteIpcIpAddr());
+//                            } else {
+//                                channel = InitHCNetSDK.getIPChannelInfo(loginNvr, device.getIpAddr());
+//                            }
+//
+//                            if (channel != null) {
+//                                break;
+//                            }
+//                        }
+//                    } else {
+//                        for(SasDevice nvrDevice : nvrDevices) {
+//                            loginNvr = InitHCNetSDK.loginDevice(nvrDevice.getIpAddr(), nvrDevice.getPort().shortValue(), nvrDevice.getUsername(), nvrDevice.getPassword());
+//                            if (loginNvr >= 0) {
+//                                macAddr = nvrDevice.getDeviceId() + nvrDevice.getDeviceType() + nvrDevice.getChannel();
+//                                this.loginHikNvrUser.put(macAddr, loginNvr);
+//                                if (device.getVideoType().equals(DeviceTypeEnum.NVR.getCode())) {
+//                                    channel = InitHCNetSDK.getIPChannelInfo(loginNvr, device.getRemoteIpcIpAddr());
+//                                } else {
+//                                    channel = InitHCNetSDK.getIPChannelInfo(loginNvr, device.getIpAddr());
+//                                }
+//
+//                                if (channel != null) {
+//                                    break;
+//                                }
+//                            }
+//                        }
+//                    }
+//                }
+//
+//                if (channel == null) {
+//                    throw new BusinessException("回放失败,NVR未找到当前设备回放", -1);
+//                }
+//
+//                streamVo = HikVideoStreamService.playBackByTime(oldMac, macAddr, bitrate, loginNvr, channel, this.mediaPort, this.mediaHttpPort, begin, end);
+//            }
+//
+//            if (!device.getVideoProtocol().equals(ProtocolEnum.DA_HUA.getCode())) {
+//                return streamVo;
+//            } else {
+//                Integer ipcChannel = null;
+//                List<SasDevice> nvrList = sasDeviceMapper.selectList(new LambdaQueryWrapper<SasDevice>().eq(SasDevice::getVideoProtocol, ProtocolEnum.DA_HUA.getCode()).eq(SasDevice::getVideoType, DeviceTypeEnum.NVR.getCode()));
+//                if (CollUtil.isNotEmpty(nvrList)) {
+//                    for(SasDevice nvrDevice : nvrList) {
+//                        DahuaNvrInfo dahuaNvrInfo = (DahuaNvrInfo)this.dhNvrUser.get(nvrDevice.getDeviceId() + nvrDevice.getDeviceType() + nvrDevice.getChannel());
+//                        if (dahuaNvrInfo != null) {
+//                            if (device.getVideoType().equals(DeviceTypeEnum.NVR.getCode())) {
+//                                ipcChannel = InitNetSDKLib.getIpcChannel(dahuaNvrInfo.getLoginHandle(), device.getRemoteIpcIpAddr(), dahuaNvrInfo.getMaxChannelNum());
+//                            } else {
+//                                ipcChannel = InitNetSDKLib.getIpcChannel(dahuaNvrInfo.getLoginHandle(), device.getIpAddr(), dahuaNvrInfo.getMaxChannelNum());
+//                            }
+//
+//                            if (ipcChannel != null) {
+//                                streamVo = DahuaVideoStreamService.playBackByTime(oldMac, device.getDeviceId() + device.getDeviceType() + device.getChannel(), dahuaNvrInfo.getLoginHandle(), ipcChannel, this.mediaPort, this.mediaHttpPort, begin, end);
+//                                return streamVo;
+//                            }
+//                        } else {
+//                            DahuaNvrInfo nvrLogin = InitNetSDKLib.nvrLogin(nvrDevice.getIpAddr(), nvrDevice.getPort(), nvrDevice.getUsername(), nvrDevice.getPassword(), nvrDevice.getDeviceId() + nvrDevice.getDeviceType() + nvrDevice.getChannel());
+//                            if (device.getVideoType().equals(DeviceTypeEnum.NVR.getCode())) {
+//                                ipcChannel = InitNetSDKLib.getIpcChannel(nvrLogin.getLoginHandle(), device.getRemoteIpcIpAddr(), nvrLogin.getMaxChannelNum());
+//                            } else {
+//                                ipcChannel = InitNetSDKLib.getIpcChannel(nvrLogin.getLoginHandle(), device.getIpAddr(), nvrLogin.getMaxChannelNum());
+//                            }
+//
+//                            if (ipcChannel != null) {
+//                                streamVo = DahuaVideoStreamService.playBackByTime(oldMac, device.getDeviceId() + device.getChannel() + device.getDeviceType(), nvrLogin.getLoginHandle(), ipcChannel, this.mediaPort, this.mediaHttpPort, begin, end);
+//                                return streamVo;
+//                            }
+//                        }
+//                    }
+//                }
+//
+//                throw new BusinessException("回放失败:未找到大华NVR设备", -1);
+//            }
+//        }
+//    }
+
+    @Override
+    public EventDetailResponse getEventDetail(String eventType, String eventId) {
+        if (StrUtil.isBlank(eventType) || StrUtil.isBlank(eventId)) {
+            return null;
+        }
+
+        switch (eventType) {
+            case "snap":
+                return getSnapEventDetail(eventId);
+            case "usb":
+                return getUsbEventDetail(eventId);
+            case "entrance":
+                return getEntranceEventDetail(eventId);
+            case "parking":
+                return getParkingEventDetail(eventId);
+            case "alarm":
+                return getAlarmEventDetail(eventId);
+            case "patrol":
+                return getPatrolEventDetail(eventId);
+            case "perception":
+                return getPerceptionEventDetail(eventId);
+            case "acquisition":
+                return getAcquisitionEventDetail(eventId);
+            case "collection":
+                return getCollectionEventDetail(eventId);
+            case "roadblock":
+                return getRoadblockEventDetail(eventId);
+            default:
+                return null;
+        }
+    }
+
+    private EventDetailResponse getSnapEventDetail(String eventId) {
+        SasSnapEvent event = sasSnapEventMapper.selectById(eventId);
+        if (event == null) return null;
+
+        EventDetailResponse infoDetail = new EventDetailResponse();
+        BeanUtil.copyProperties(event, infoDetail);
+
+        SasPerson person = sasPersonMapper.selectById(event.getPersonCode());
+        if (person != null) {
+            SasSystemConfig systemConfig = sasSystemConfigMapper.selectOne(new LambdaQueryWrapper<SasSystemConfig>().last("limit 1"));
+            SasCredentialTypeCode credentialTypeCode = sasCredentialTypeCodeMapper.selectById(person.getCredentialType());
+            if (credentialTypeCode != null) {
+                infoDetail.setCredentialType(credentialTypeCode.getName());
+            }
+
+            if (systemConfig != null && !Boolean.TRUE.equals(systemConfig.getMaskIdCardNo())) {
+                infoDetail.setCredentialNo(person.getCredentialNo());
+            }
+
+            infoDetail.setName(person.getName());
+        }
+
+        setGisInfo(infoDetail, event.getGisId());
+        infoDetail.setCreateTime(event.getCreateTime());
+        setPicInfo(infoDetail, event.getEventPicId(), true);
+        setPicInfo(infoDetail, event.getScenePicId(), false);
+
+        SasSnapTypeCode code = sasSnapTypeCodeMapper.selectById(event.getEventCode());
+        if (code != null) {
+            infoDetail.setEventTypeName(code.getName());
+        }
+
+        setDeviceInfo(infoDetail, event.getDeviceId(), event.getChannel(), SystemTypeCodeEnum.snap.getCode(), event.getNote());
+
+        infoDetail.setDeviceType(SystemTypeCodeEnum.snap.getCode());
+        return infoDetail;
+    }
+
+    private EventDetailResponse getUsbEventDetail(String eventId) {
+        SasUsbEvent event = sasUsbEventMapper.selectById(eventId);
+        if (event == null) return null;
+
+        EventDetailResponse infoDetail = new EventDetailResponse();
+        BeanUtil.copyProperties(event, infoDetail);
+        infoDetail.setCreateTime(event.getCreateTime());
+
+        SasUsbEventCode code = sasUsbEventCodeMapper.selectById(event.getEventCode());
+        if (code != null) {
+            infoDetail.setEventTypeName(code.getName());
+        }
+
+        setDeviceInfo(infoDetail, event.getDeviceId(), event.getChannel(), SystemTypeCodeEnum.usb.getCode(), event.getNote());
+        infoDetail.setDeviceType(SystemTypeCodeEnum.usb.getCode());
+        return infoDetail;
+    }
 
-        HomepageInfoResponse.ServerInfo serverInfo = new HomepageInfoResponse.ServerInfo();
-        serverInfo.setMemoryMaxMb(maxMemory == Long.MAX_VALUE ? null : maxMemory / (1024 * 1024));
-        serverInfo.setMemoryUsedMb(usedMemory / (1024 * 1024));
-        serverInfo.setMemoryFreeMb(freeMemory / (1024 * 1024));
-        serverInfo.setAvailableProcessors(runtime.availableProcessors());
-        serverInfo.setServerTime(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
-        return serverInfo;
+    private EventDetailResponse getEntranceEventDetail(String eventId) {
+        SasEntranceEvent event = sasEntranceEventMapper.selectById(eventId);
+        if (event == null) return null;
+
+        EventDetailResponse infoDetail = new EventDetailResponse();
+        BeanUtil.copyProperties(event, infoDetail);
+        infoDetail.setCreateTime(event.getCreateTime());
+
+        SasCredentialTypeCode credentialTypeCode = sasCredentialTypeCodeMapper.selectById(event.getCertifiedType());
+        if (credentialTypeCode != null) {
+            infoDetail.setCertifiedTypeName(credentialTypeCode.getName());
+        }
+
+        SasSystemConfig systemConfig = sasSystemConfigMapper.selectOne(new LambdaQueryWrapper<SasSystemConfig>().last("limit 1"));
+        if (systemConfig != null && !Boolean.TRUE.equals(systemConfig.getMaskIdCardNo())) {
+            String masked = event.getCertifiedNo();
+            if (StrUtil.isNotBlank(masked) && masked.length() > 8) {
+                masked = IdcardUtil.hide(masked, 4, masked.length() - 4);
+            }
+            infoDetail.setCertifiedNo(masked);
+        }
+
+        setPicInfo(infoDetail, event.getPicId(), true);
+
+        if (event.getEventCode() != null) {
+            if (event.getEventCode() % 10 == 0) {
+                SasEntranceEventCode code = sasEntranceEventCodeMapper.selectById(event.getEventCode());
+                if (code != null) {
+                    infoDetail.setEventCode(String.valueOf(code.getCode()));
+                    infoDetail.setEventTypeName(code.getName());
+                }
+            } else if (event.getEventCode() % 10 == 1) {
+                SasPeopleTypeCode code = sasPeopleTypeCodeMapper.selectById((event.getEventCode() - 1) / 10);
+                if (code != null) {
+                    infoDetail.setEventCode(String.valueOf(code.getCode()));
+                    infoDetail.setEventTypeName(code.getName() + "进");
+                }
+            } else if (event.getEventCode() % 10 == 2) {
+                SasPeopleTypeCode code = sasPeopleTypeCodeMapper.selectById((event.getEventCode() - 2) / 10);
+                if (code != null) {
+                    infoDetail.setEventCode(code.getCode());
+                    infoDetail.setEventTypeName(code.getName() + "出");
+                }
+            }
+        }
+
+        setDeviceInfo(infoDetail, event.getDeviceId(), event.getChannel(), SystemTypeCodeEnum.entrance.getCode(), event.getNote());
+        infoDetail.setDeviceType(SystemTypeCodeEnum.entrance.getCode());
+        return infoDetail;
+    }
+
+    private EventDetailResponse getParkingEventDetail(String eventId) {
+        SasParkingEvent event = sasParkingEventMapper.selectById(eventId);
+        if (event == null) return null;
+
+        EventDetailResponse infoDetail = new EventDetailResponse();
+        BeanUtil.copyProperties(event, infoDetail);
+        infoDetail.setCreateTime(event.getCreateTime());
+
+        setGisInfo(infoDetail, event.getGisId());
+
+        SasCarTypeCode carType = sasCarTypeCodeMapper.selectById(event.getCarType());
+        if (carType != null) {
+            infoDetail.setCarType(carType.getName());
+        }
+
+        SasPlateTypeCode plateTypeCode = sasPlateTypeCodeMapper.selectById(event.getPlateType());
+        if (plateTypeCode != null) {
+            infoDetail.setPlateType(plateTypeCode.getName());
+        }
+
+        setPicInfo(infoDetail, event.getEventPicId(), true);
+        setPicInfo(infoDetail, event.getPlatePicId(), false);
+
+        SasParkingEventCode code = sasParkingEventCodeMapper.selectById(event.getEventCode());
+        if (code != null) {
+            infoDetail.setEventTypeName(code.getName());
+        }
+
+        SasPlateColor plateColor = sasPlateColorMapper.selectById(event.getPlateColor());
+        if (plateColor != null) {
+            infoDetail.setPlateColor(plateColor.getName());
+        }
+
+        setDeviceInfo(infoDetail, event.getDeviceId(), event.getChannel(), SystemTypeCodeEnum.parking.getCode(), event.getNote());
+        infoDetail.setDeviceType(SystemTypeCodeEnum.parking.getCode());
+        return infoDetail;
+    }
+
+    private EventDetailResponse getAlarmEventDetail(String eventId) {
+        SasAlarsasEvent event = sasAlarsasEventMapper.selectById(eventId);
+        if (event == null) return null;
+
+        EventDetailResponse infoDetail = new EventDetailResponse();
+        BeanUtil.copyProperties(event, infoDetail);
+        infoDetail.setCreateTime(event.getCreateTime());
+        setGisInfo(infoDetail, event.getGisId());
+        setPicInfo(infoDetail, event.getPicId(), true);
+
+        SasAlarsasEventCode code = sasAlarsasEventCodeMapper.selectById(event.getEventCode());
+        if (code != null) {
+            infoDetail.setEventTypeName(code.getName());
+        }
+
+        setDeviceInfo(infoDetail, event.getDeviceId(), event.getChannel(), SystemTypeCodeEnum.alarm.getCode(), event.getNote());
+        infoDetail.setDeviceType(SystemTypeCodeEnum.alarm.getCode());
+        return infoDetail;
+    }
+
+    private EventDetailResponse getPatrolEventDetail(String eventId) {
+        SasPatrolEvent event = sasPatrolEventMapper.selectById(eventId);
+        if (event == null) return null;
+
+        EventDetailResponse infoDetail = new EventDetailResponse();
+        BeanUtil.copyProperties(event, infoDetail);
+        infoDetail.setCreateTime(event.getCreateTime());
+        setGisInfo(infoDetail, event.getGisId());
+        setPicInfo(infoDetail, event.getPicId(), true);
+
+        SasCredentialTypeCode credentialTypeCode = sasCredentialTypeCodeMapper.selectById(event.getCredentialType());
+        if (credentialTypeCode != null) {
+            infoDetail.setCredentialType(credentialTypeCode.getName());
+        }
+
+        SasSystemConfig systemConfig = sasSystemConfigMapper.selectOne(new LambdaQueryWrapper<SasSystemConfig>().last("limit 1"));
+        if (systemConfig != null && !Boolean.TRUE.equals(systemConfig.getMaskIdCardNo())) {
+            String masked = event.getCredentialNo();
+            if (StrUtil.isNotBlank(masked) && masked.length() > 8) {
+                masked = IdcardUtil.hide(masked, 4, masked.length() - 4);
+            }
+            infoDetail.setCredentialNo(masked);
+        }
+
+        SasPatrolEventCode code = sasPatrolEventCodeMapper.selectById(event.getEventCode());
+        if (code != null) {
+            infoDetail.setEventTypeName(code.getName());
+        }
+
+        setDeviceInfo(infoDetail, event.getDeviceId(), event.getChannel(), SystemTypeCodeEnum.patrol.getCode(), event.getNote());
+        infoDetail.setDeviceType(SystemTypeCodeEnum.patrol.getCode());
+        return infoDetail;
+    }
+
+    private EventDetailResponse getPerceptionEventDetail(String eventId) {
+        SasPerceptionEvent event = sasPerceptionEventMapper.selectById(eventId);
+        if (event == null) return null;
+
+        EventDetailResponse infoDetail = new EventDetailResponse();
+        BeanUtil.copyProperties(event, infoDetail);
+        infoDetail.setCreateTime(event.getCreateTime());
+        setGisInfo(infoDetail, event.getGisId());
+        setPicInfo(infoDetail, event.getPicId(), true);
+
+        SasPerceptionEventCode code = sasPerceptionEventCodeMapper.selectById(event.getEventCode());
+        if (code != null) {
+            infoDetail.setEventTypeName(code.getName());
+        }
+
+        setDeviceInfo(infoDetail, event.getDeviceId(), event.getChannel(), SystemTypeCodeEnum.perception.getCode(), event.getNote());
+        infoDetail.setDeviceType(SystemTypeCodeEnum.perception.getCode());
+        return infoDetail;
+    }
+
+    private EventDetailResponse getAcquisitionEventDetail(String eventId) {
+        SasAcquisitionEvent event = sasAcquisitionEventMapper.selectById(eventId);
+        if (event == null) return null;
+
+        EventDetailResponse infoDetail = new EventDetailResponse();
+        BeanUtil.copyProperties(event, infoDetail);
+        infoDetail.setCreateTime(event.getCreateTime());
+        setGisInfo(infoDetail, event.getGisId());
+        setPicInfo(infoDetail, event.getPicId(), true);
+
+        SasAcquisitionEventCode code = sasAcquisitionEventCodeMapper.selectById(event.getEventCode());
+        if (code != null) {
+            infoDetail.setEventTypeName(code.getName());
+        }
+
+        infoDetail.setDeviceType(SystemTypeCodeEnum.acquisition.getCode());
+        setDeviceInfo(infoDetail, event.getDeviceId(), event.getChannel(), SystemTypeCodeEnum.acquisition.getCode(), event.getNote());
+        return infoDetail;
+    }
+
+    private EventDetailResponse getCollectionEventDetail(String eventId) {
+        SasCollectionEvent event = sasCollectionEventMapper.selectById(eventId);
+        if (event == null) return null;
+
+        EventDetailResponse infoDetail = new EventDetailResponse();
+        BeanUtil.copyProperties(event, infoDetail);
+        infoDetail.setCreateTime(event.getCreateTime());
+        setGisInfo(infoDetail, event.getGisId());
+        setPicInfo(infoDetail, event.getPicId(), true);
+        setPicInfo(infoDetail, event.getScenePicId(), false);
+
+        SasCollectionEventCode code = sasCollectionEventCodeMapper.selectById(event.getEventCode());
+        if (code != null) {
+            infoDetail.setEventTypeName(code.getName());
+        }
+
+        setDeviceInfo(infoDetail, event.getDeviceId(), event.getChannel(), SystemTypeCodeEnum.collection.getCode(), event.getNote());
+        infoDetail.setDeviceType(SystemTypeCodeEnum.collection.getCode());
+        return infoDetail;
+    }
+
+    private EventDetailResponse getRoadblockEventDetail(String eventId) {
+        SasRoadblockEvent event = sasRoadblockEventMapper.selectById(eventId);
+        if (event == null) return null;
+
+        EventDetailResponse infoDetail = new EventDetailResponse();
+        BeanUtil.copyProperties(event, infoDetail);
+        infoDetail.setCreateTime(event.getCreateTime());
+        setGisInfo(infoDetail, event.getGisId());
+        setPicInfo(infoDetail, event.getPicId(), true);
+
+        SasRoadblockEventCode code = sasRoadblockEventCodeMapper.selectById(event.getEventCode());
+        if (code != null) {
+            infoDetail.setEventTypeName(code.getName());
+        }
+
+        setDeviceInfo(infoDetail, event.getDeviceId(), event.getChannel(), SystemTypeCodeEnum.roadblock.getCode(), event.getNote());
+        infoDetail.setDeviceType(SystemTypeCodeEnum.roadblock.getCode());
+        return infoDetail;
+    }
+
+    private void setGisInfo(EventDetailResponse infoDetail, String gisId) {
+        if (StrUtil.isBlank(gisId)) return;
+        SasGis gis = sasGisMapper.selectById(gisId);
+        if (gis != null) {
+            EventDetailResponse.GisInfo gisInfo = new EventDetailResponse.GisInfo();
+            BeanUtil.copyProperties(gis, gisInfo);
+            infoDetail.setGisInfo(gisInfo);
+        }
+    }
+
+    private void setPicInfo(EventDetailResponse infoDetail, String picId, boolean isEventUrl) {
+        if (StrUtil.isBlank(picId)) return;
+        SasPic pic = sasPicMapper.selectById(picId);
+        if (pic != null && StrUtil.isNotBlank(pic.getUrl()) && StrUtil.isNotBlank(pic.getPath())) {
+            if (isEventUrl) {
+                infoDetail.setEventUrl(pic.getUrl() + pic.getPath());
+            } else {
+                infoDetail.setSceneUrl(pic.getUrl() + pic.getPath());
+            }
+        }
+    }
+
+    private void setDeviceInfo(EventDetailResponse infoDetail, String deviceId, Integer channel, Integer deviceType, String note) {
+        LambdaQueryWrapper<SasDevice> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(SasDevice::getDeviceId, deviceId);
+        if (channel != null) {
+            wrapper.eq(SasDevice::getChannel, channel);
+        }
+        if (deviceType != null) {
+            wrapper.eq(SasDevice::getDeviceType, deviceType);
+        }
+        
+        SasDevice device = sasDeviceMapper.selectOne(wrapper);
+        if (device != null) {
+            if (StrUtil.isBlank(note)) {
+                infoDetail.setNote(device.getNote());
+            }
+            infoDetail.setAddress(device.getAddress());
+        }
     }
 
     private HomepageInfoResponse.CameraItem toCameraItem(SasDevice d) {
@@ -129,16 +834,15 @@ public class SasHomepageServiceImpl implements SasHomepageService {
     @Override
     public CommonPage<IntelligentEventItem> getAlertHistory(HomepageAlertHistoryRequest request) {
         if (!"snap".equals(request.getEventType())) {
-            return new CommonPage<>(Collections.emptyList(), 0L, request.getCurrent().longValue(), request.getSize().longValue());
+            return new CommonPage<>(Collections.emptyList(), 0L, request.getCurrent(), request.getSize());
         }
-        com.baomidou.mybatisplus.extension.plugins.pagination.Page<SasSnapEvent> page =
-                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(request.getCurrent(), request.getSize());
+        Page<SasSnapEvent> page = new Page<>(request.getCurrent(), request.getSize());
         LambdaQueryWrapper<SasSnapEvent> wrapper = new LambdaQueryWrapper<>();
         wrapper.eq(SasSnapEvent::getNotify, true);
         wrapper.orderByDesc(SasSnapEvent::getTriggerTime);
         page = sasSnapEventMapper.selectPage(page, wrapper);
-        List<SasSnapEvent> records = page.getRecords() == null ? Collections.emptyList() : page.getRecords();
-        List<IntelligentEventItem> list = records.stream().map(this::snapToEventItem).collect(Collectors.toList());
+        List<IntelligentEventItem> list = (page.getRecords() == null ? Collections.<SasSnapEvent>emptyList() : page.getRecords())
+                .stream().map(this::snapToEventItem).collect(Collectors.toList());
         return new CommonPage<>(list, page.getTotal(), page.getCurrent(), page.getSize());
     }
 
@@ -157,4 +861,74 @@ public class SasHomepageServiceImpl implements SasHomepageService {
         item.setScene(e.getScene());
         return item;
     }
-}
+
+    @Override
+    public SystemResourceResponse getSystemResource() {
+        SystemResourceResponse response = new SystemResourceResponse();
+        DecimalFormat df = new DecimalFormat("#0.00");
+
+        // CPU信息
+        SystemResourceResponse.CpuInfo cpu = new SystemResourceResponse.CpuInfo();
+        Runtime runtime = Runtime.getRuntime();
+        cpu.setCoreCount(runtime.availableProcessors());
+        
+        // 获取CPU使用率
+        com.sun.management.OperatingSystemMXBean osBean = 
+            (com.sun.management.OperatingSystemMXBean) java.lang.management.ManagementFactory.getOperatingSystemMXBean();
+        double cpuUsage = osBean.getSystemCpuLoad() * 100;
+        cpu.setUsageRate(df.format(cpuUsage) + "%");
+        response.setCpu(cpu);
+
+        // 内存信息
+        SystemResourceResponse.MemoryInfo memory = new SystemResourceResponse.MemoryInfo();
+        long maxMemory = runtime.maxMemory();
+        long totalMemory = runtime.totalMemory();
+        long freeMemory = runtime.freeMemory();
+        long usedMemory = totalMemory - freeMemory;
+        
+        double totalMemoryGB = maxMemory / (1024.0 * 1024.0 * 1024.0);
+        double usedMemoryGB = usedMemory / (1024.0 * 1024.0 * 1024.0);
+        double freeMemoryGB = (maxMemory - usedMemory) / (1024.0 * 1024.0 * 1024.0);
+        double memoryUsageRate = (usedMemory * 100.0) / maxMemory;
+        
+        memory.setTotalSize(df.format(totalMemoryGB) + " GB");
+        memory.setUsedSize(df.format(usedMemoryGB) + " GB");
+        memory.setFreeSize(df.format(freeMemoryGB) + " GB");
+        memory.setUsageRate(df.format(memoryUsageRate) + "%");
+        response.setMemory(memory);
+
+        // 磁盘信息
+        SystemResourceResponse.DiskInfo disk = new SystemResourceResponse.DiskInfo();
+        File[] roots = File.listRoots();
+        long totalSpace = 0;
+        long usableSpace = 0;
+        for (File root : roots) {
+            totalSpace += root.getTotalSpace();
+            usableSpace += root.getUsableSpace();
+        }
+        long usedSpace = totalSpace - usableSpace;
+        
+        double totalSpaceGB = totalSpace / (1024.0 * 1024.0 * 1024.0);
+        double usedSpaceGB = usedSpace / (1024.0 * 1024.0 * 1024.0);
+        double usableSpaceGB = usableSpace / (1024.0 * 1024.0 * 1024.0);
+        double diskUsageRate = totalSpace > 0 ? (usedSpace * 100.0) / totalSpace : 0;
+        
+        disk.setTotalSize(df.format(totalSpaceGB) + " GB");
+        disk.setUsedSize(df.format(usedSpaceGB) + " GB");
+        disk.setFreeSize(df.format(usableSpaceGB) + " GB");
+        disk.setUsageRate(df.format(diskUsageRate) + "%");
+        response.setDisk(disk);
+
+        // Agbox/MetaBus信息
+        SystemResourceResponse.AgboxInfo agbox = new SystemResourceResponse.AgboxInfo();
+        SasConfig config = sasConfigMapper.selectById(1);
+        if (config != null) {
+            agbox.setHost(config.getHost());
+            agbox.setPort(config.getPort());
+            agbox.setStatus(this.mqttService.getConnectionStatus());
+            agbox.setEventListenStatus(this.mqttService.getListeningStatus());
+        }
+        response.setAgboxMetaBus(agbox);
+        return response;
+    }
+}

文件差異過大導致無法顯示
+ 0 - 264
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/impl/SasIntelligentServiceImpl.java


+ 1 - 1
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/impl/SasOneStandardSixRealitiesServiceImpl.java

@@ -815,7 +815,7 @@ public class SasOneStandardSixRealitiesServiceImpl implements SasOneStandardSixR
             if (v.getGisId() != null && !v.getGisId().isEmpty()) gisIds.add(v.getGisId());
         }
         if (gisIds.isEmpty()) return Collections.emptyMap();
-        List<SasGis> gisList = sasGisMapper.selectByIds(new ArrayList<>(gisIds));
+        List<SasGis> gisList = (List<SasGis>) sasGisMapper.selectByIds(new ArrayList<>(gisIds));
         Map<String, SasGis> map = new HashMap<>(gisList.size());
         for (SasGis g : gisList) {
             map.put(g.getId(), g);

+ 144 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/EventDetailResponse.java

@@ -0,0 +1,144 @@
+package com.usky.sas.service.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 事件详情响应
+ */
+@Data
+@ApiModel("事件详情响应")
+public class EventDetailResponse {
+
+    @ApiModelProperty("事件ID")
+    private String eventId;
+
+    @ApiModelProperty("设备ID")
+    private String deviceId;
+
+    @ApiModelProperty("设备类型")
+    private Integer deviceType;
+
+    @ApiModelProperty("通道号")
+    private Integer channel;
+
+    @ApiModelProperty("触发时间")
+    private LocalDateTime triggerTime;
+
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("事件代码")
+    private String eventCode;
+
+    @ApiModelProperty("事件类型名称")
+    private String eventTypeName;
+
+    @ApiModelProperty("备注")
+    private String note;
+
+    @ApiModelProperty("地址")
+    private String address;
+
+    @ApiModelProperty("事件图片URL")
+    private String eventUrl;
+
+    @ApiModelProperty("场景图片URL")
+    private String sceneUrl;
+
+    // Snap 专用字段
+    @ApiModelProperty("人员编码")
+    private String personCode;
+
+    @ApiModelProperty("人员姓名")
+    private String name;
+
+    @ApiModelProperty("证件类型")
+    private String credentialType;
+
+    @ApiModelProperty("证件号码")
+    private String credentialNo;
+
+    @ApiModelProperty("相似度")
+    private Integer similarity;
+
+    @ApiModelProperty("是否通知")
+    private Boolean notify;
+
+    @ApiModelProperty("是否场景")
+    private Boolean scene;
+
+    // Entrance 专用字段
+    @ApiModelProperty("认证类型")
+    private Integer certifiedType;
+
+    @ApiModelProperty("认证类型名称")
+    private String certifiedTypeName;
+
+    @ApiModelProperty("认证号码")
+    private String certifiedNo;
+
+    @ApiModelProperty("电话")
+    private String phone;
+
+    @ApiModelProperty("卡号")
+    private String cardId;
+
+    // Parking 专用字段
+    @ApiModelProperty("入口编码")
+    private String entranceCode;
+
+    @ApiModelProperty("车牌号")
+    private String plateNo;
+
+    @ApiModelProperty("车牌类型")
+    private String plateType;
+
+    @ApiModelProperty("车牌颜色")
+    private String plateColor;
+
+    @ApiModelProperty("车辆类型")
+    private String carType;
+
+    @ApiModelProperty("通行类型")
+    private Integer accessType;
+
+    // Alarm 专用字段
+    @ApiModelProperty("关联人员")
+    private String relPerson;
+
+    @ApiModelProperty("处理人员")
+    private String dealPerson;
+
+    @ApiModelProperty("事件系统")
+    private Integer eventSystem;
+
+    // Patrol 专用字段
+    @ApiModelProperty("类型名称")
+    private String typeName;
+
+    // GIS 信息
+    @ApiModelProperty("GIS信息")
+    private GisInfo gisInfo;
+
+    @Data
+    @ApiModel("GIS信息")
+    public static class GisInfo {
+        @ApiModelProperty("GIS ID")
+        private String id;
+
+        @ApiModelProperty("名称")
+        private String name;
+
+        @ApiModelProperty("经度")
+        private Double longitude;
+
+        @ApiModelProperty("纬度")
+        private Double latitude;
+
+        @ApiModelProperty("地址")
+        private String address;
+    }
+}

+ 15 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/HomepageAlertHistoryRequest.java

@@ -1,19 +1,34 @@
 package com.usky.sas.service.vo;
 
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotBlank;
+
 /**
  * 首页预警历史分页请求
  */
 @Data
+@ApiModel("首页预警历史查询请求")
 public class HomepageAlertHistoryRequest {
 
+    @ApiModelProperty(value = "当前页码", example = "1")
+    @Min(value = 1, message = "页码必须大于0")
     private Integer current = 1;
 
+    @ApiModelProperty(value = "每页大小", example = "10")
+    @Min(value = 1, message = "每页大小必须大于0")
+    @Max(value = 100, message = "每页大小不能超过100")
     private Integer size = 10;
 
     /**
      * 事件类型(当前仅 snap 支持开启通知的预警)
      */
+    @ApiModelProperty(value = "事件类型", example = "snap", allowableValues = "snap")
+    @NotBlank(message = "事件类型不能为空")
     private String eventType = "snap";
+
 }

+ 5 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/IntelligentEventItem.java

@@ -1,5 +1,6 @@
 package com.usky.sas.service.vo;
 
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.time.LocalDateTime;
@@ -31,6 +32,10 @@ public class IntelligentEventItem {
 
     private String personName;
 
+    private String note;
+
+    private String address;
+
     // snap 专用字段
     private String scenePicId;
 

+ 21 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/IntelligentEventPageRequest.java

@@ -1,22 +1,43 @@
 package com.usky.sas.service.vo;
 
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
 import java.time.LocalDateTime;
 
 @Data
+@ApiModel("智能事件分页查询请求")
 public class IntelligentEventPageRequest {
 
+    /**
+     * 系统类型(snap、usb、entrance、parking、alarm、patrol、perception、acquisition、collection、roadblock)
+     */
+    @ApiModelProperty(value = "事件类型", example = "snap", 
+            allowableValues = "snap,usb,entrance,parking,alarm,patrol,perception,acquisition,collection,roadblock")
     private String eventType;
 
+    @ApiModelProperty(value = "当前页码", example = "1")
+    @Min(value = 1, message = "页码必须大于0")
     private Integer current = 1;
 
+    @ApiModelProperty(value = "每页大小", example = "10")
+    @Min(value = 1, message = "每页大小必须大于0")
+    @Max(value = 100, message = "每页大小不能超过100")
     private Integer size = 10;
 
+    @ApiModelProperty(value = "开始时间")
     private LocalDateTime startTime;
 
+    @ApiModelProperty(value = "结束时间")
     private LocalDateTime endTime;
 
+    @ApiModelProperty(value = "设备ID")
     private String deviceId;
+
+    @ApiModelProperty(value = "事件代码(多个用逗号分隔)", example = "1,2,3")
+    private String eventCode;
 }
 

+ 66 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/SystemResourceResponse.java

@@ -0,0 +1,66 @@
+package com.usky.sas.service.vo;
+
+import lombok.Data;
+
+/**
+ * 系统资源信息响应
+ */
+@Data
+public class SystemResourceResponse {
+
+    /** CPU信息 */
+    private CpuInfo cpu;
+
+    /** 内存信息 */
+    private MemoryInfo memory;
+
+    /** 磁盘信息 */
+    private DiskInfo disk;
+
+    /** Agbox/MetaBus信息 */
+    private AgboxInfo agboxMetaBus;
+
+    @Data
+    public static class CpuInfo {
+        /** CPU核心数 */
+        private Integer coreCount;
+        /** CPU使用率 */
+        private String usageRate;
+    }
+
+    @Data
+    public static class MemoryInfo {
+        /** 总内存大小 */
+        private String totalSize;
+        /** 已使用内存大小 */
+        private String usedSize;
+        /** 空闲内存大小 */
+        private String freeSize;
+        /** 内存使用率 */
+        private String usageRate;
+    }
+
+    @Data
+    public static class DiskInfo {
+        /** 总磁盘大小 */
+        private String totalSize;
+        /** 已使用磁盘大小 */
+        private String usedSize;
+        /** 空闲磁盘大小 */
+        private String freeSize;
+        /** 磁盘使用率 */
+        private String usageRate;
+    }
+
+    @Data
+    public static class AgboxInfo {
+        /** 主机地址 */
+        private String host;
+        /** 端口 */
+        private String port;
+        /** 状态 */
+        private boolean status;
+        /** 事件监听状态 */
+        private boolean eventListenStatus;
+    }
+}

+ 18 - 0
service-sas/service-sas-biz/src/main/java/com/usky/sas/service/vo/VideoStreamVo.java

@@ -0,0 +1,18 @@
+package com.usky.sas.service.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class VideoStreamVo implements Serializable {
+    @ApiModelProperty("视频流播放地址")
+    private String url;
+    @ApiModelProperty("用户句柄")
+    private Integer userId;
+    @ApiModelProperty("视频流句柄")
+    private Long handle;
+    @ApiModelProperty("回放内存句柄")
+    private String mac;
+}

+ 10 - 0
service-sas/service-sas-biz/src/main/resources/mapper/sas/SasPersonTypeCodeMapper.xml

@@ -0,0 +1,10 @@
+<?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.usky.sas.mapper.SasPersonTypeCodeMapper">
+
+    <resultMap id="BaseResultMap" type="com.usky.sas.domain.SasPersonTypeCode">
+        <id column="code" property="code"/>
+        <result column="name" property="name"/>
+    </resultMap>
+
+</mapper>

+ 12 - 0
service-sas/service-sas-biz/src/main/resources/mapper/sas/SasSnapTypeCodeMapper.xml

@@ -0,0 +1,12 @@
+<?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.usky.sas.mapper.SasSnapTypeCodeMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.sas.domain.SasSnapTypeCode">
+        <id column="code" property="code" />
+        <result column="name" property="name" />
+        <result column="is_used" property="isUsed" />
+    </resultMap>
+
+</mapper>

部分文件因文件數量過多而無法顯示