From eea367d6d7b5315e6ddddfaa9d992842f013e71f Mon Sep 17 00:00:00 2001 From: lin <648540858@qq.com> Date: Sat, 12 Apr 2025 21:24:02 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BD=95=E5=83=8Fseek?= =?UTF-8?q?=E5=92=8C=E5=80=8D=E9=80=9F=E6=92=AD=E6=94=BE=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gb28181/service/impl/PlayServiceImpl.java | 1 + .../service/IMediaNodeServerService.java | 1 + .../media/service/IMediaServerService.java | 2 + .../service/impl/MediaServerServiceImpl.java | 11 ++++ .../media/zlm/ZLMMediaNodeServerService.java | 11 ++++ .../iot/vmp/media/zlm/ZLMRESTfulUtils.java | 31 +++++++++ .../service/ICloudRecordService.java | 7 ++- .../service/impl/CloudRecordServiceImpl.java | 44 ++++++++++--- .../RedisRpcCloudRecordController.java | 2 +- .../dao/CloudRecordServiceMapper.java | 9 ++- .../cloudRecord/CloudRecordController.java | 63 ++++++++++++++++++- .../iot/vmp/vmanager/log/LogController.java | 18 ------ 12 files changed, 165 insertions(+), 35 deletions(-) rename src/main/java/com/genersoft/iot/vmp/{gb28181 => }/service/ICloudRecordService.java (88%) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java index 3bafa6a20..f952041f3 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java @@ -28,6 +28,7 @@ import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent; import com.genersoft.iot.vmp.media.event.media.MediaNotFoundEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; +import com.genersoft.iot.vmp.service.ICloudRecordService; import com.genersoft.iot.vmp.service.IReceiveRtpServerService; import com.genersoft.iot.vmp.service.ISendRtpServerService; import com.genersoft.iot.vmp.service.bean.*; diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java index 6b2a327f5..447430feb 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java @@ -70,4 +70,5 @@ public interface IMediaNodeServerService { List listRtpServer(MediaServer mediaServer); + void loadMP4File(MediaServer mediaServer, String app, String stream, String datePath); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java index 9cf145ad3..10d3f5375 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java @@ -159,4 +159,6 @@ public interface IMediaServerService { int createRTPServer(MediaServer mediaServerItem, String streamId, long ssrc, Integer port, boolean onlyAuto, boolean disableAudio, boolean reUsePort, Integer tcpMode); List listRtpServer(MediaServer mediaServer); + + StreamInfo loadMP4File(MediaServer mediaServer, String app, String stream, String datePath); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index 98f9c7518..bc578a214 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -966,4 +966,15 @@ public class MediaServerServiceImpl implements IMediaServerService { } mediaNodeServerService.stopProxy(mediaServer, streamKey); } + + @Override + public StreamInfo loadMP4File(MediaServer mediaServer, String app, String stream, String datePath) { + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); + if (mediaNodeServerService == null) { + log.info("[loadMP4File] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); + throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到mediaServer对应的实现类"); + } + mediaNodeServerService.loadMP4File(mediaServer, app, stream, datePath); + return getStreamInfoByAppAndStream(mediaServer, app, stream, null, null); + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index 0cdf62689..c5f8ea687 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -549,4 +549,15 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { } return result; } + + @Override + public void loadMP4File(MediaServer mediaServer, String app, String stream, String datePath) { + JSONObject jsonObject = zlmresTfulUtils.loadMP4File(mediaServer, app, stream, datePath); + if (jsonObject == null) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "请求失败"); + } + if (jsonObject.getInteger("code") != 0) { + throw new ControllerException(jsonObject.getInteger("code"), jsonObject.getString("msg")); + } + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java index 9125858cd..16e429669 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java @@ -25,6 +25,7 @@ public class ZLMRESTfulUtils { private OkHttpClient client; + public interface RequestCallback{ void run(JSONObject response); } @@ -415,4 +416,34 @@ public class ZLMRESTfulUtils { param.put("name", fileName); return sendPost(mediaServerItem, "deleteRecordDirectory",param, null); } + + public JSONObject loadMP4File(MediaServer mediaServer, String app, String stream, String datePath) { + Map param = new HashMap<>(1); + param.put("vhost", "__defaultVhost__"); + param.put("app", app); + param.put("stream", stream); + param.put("file_path", datePath); + param.put("file_repeat", "0"); + param.put("auto_close", "1"); + return sendPost(mediaServer, "loadMP4File",param, null); + } + + public JSONObject setRecordSpeed(MediaServer mediaServer, String app, String stream, int speed, String schema) { + Map param = new HashMap<>(1); + param.put("vhost", "__defaultVhost__"); + param.put("app", app); + param.put("stream", stream); + param.put("speed", speed); + param.put("schema", schema); + return sendPost(mediaServer, "setRecordSpeed",param, null); + } + + public JSONObject seekRecordStamp(MediaServer mediaServer, String app, String stream, long stamp) { + Map param = new HashMap<>(1); + param.put("vhost", "__defaultVhost__"); + param.put("app", app); + param.put("stream", stream); + param.put("stamp", stamp); + return sendPost(mediaServer, "seekRecordStamp",param, null); + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/ICloudRecordService.java b/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java similarity index 88% rename from src/main/java/com/genersoft/iot/vmp/gb28181/service/ICloudRecordService.java rename to src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java index 5738a8202..515ddae5e 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/ICloudRecordService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java @@ -1,10 +1,11 @@ -package com.genersoft.iot.vmp.gb28181.service; +package com.genersoft.iot.vmp.service; import com.alibaba.fastjson2.JSONArray; +import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; -import com.genersoft.iot.vmp.vmanager.bean.StreamContent; +import com.genersoft.iot.vmp.service.bean.ErrorCallback; import com.github.pagehelper.PageInfo; import java.util.List; @@ -57,5 +58,5 @@ public interface ICloudRecordService { /** * 加载录像文件,形成录像流 */ - StreamContent loadRecord(String app, String stream, String date); + void loadRecord(String app, String stream, String date, ErrorCallback callback); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java index 82840b479..7b2901469 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java @@ -2,23 +2,28 @@ package com.genersoft.iot.vmp.service.impl; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; +import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; -import com.genersoft.iot.vmp.gb28181.service.ICloudRecordService; +import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.bean.MediaServer; +import com.genersoft.iot.vmp.media.event.hook.Hook; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; +import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.media.event.media.MediaRecordMp4Event; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; +import com.genersoft.iot.vmp.service.ICloudRecordService; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; +import com.genersoft.iot.vmp.service.bean.ErrorCallback; import com.genersoft.iot.vmp.service.redisMsg.IRedisRpcPlayService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.dao.CloudRecordServiceMapper; import com.genersoft.iot.vmp.utils.CloudRecordUtils; import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; -import com.genersoft.iot.vmp.vmanager.bean.StreamContent; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import lombok.extern.slf4j.Slf4j; @@ -58,6 +63,9 @@ public class CloudRecordServiceImpl implements ICloudRecordService { @Autowired private IRedisRpcPlayService redisRpcPlayService; + @Autowired + private HookSubscribe subscribe; + @Override public PageInfo getList(int page, int count, String query, String app, String stream, String startTime, String endTime, List mediaServerItems, String callId, Boolean ascOrder) { @@ -278,18 +286,40 @@ public class CloudRecordServiceImpl implements ICloudRecordService { } @Override - public StreamContent loadRecord(String app, String stream, String date) { + public void loadRecord(String app, String stream, String date, ErrorCallback callback) { long startTimestamp = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestampMs(date + " 00:00:00"); long endTimestamp = startTimestamp + 24 * 60 * 60 * 1000; - List mediaServerIds = cloudRecordServiceMapper.queryMediaServerInRecord(app, stream, startTimestamp, endTimestamp); + List mediaServerIds = cloudRecordServiceMapper.queryMediaServerId(app, stream, startTimestamp, endTimestamp); if (mediaServerIds.isEmpty()) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "此时间无录像"); } + if (mediaServerIds.size() > 1) { - log.info("[云端录像] loadMP4File时发现录像文件分布在不通的zlm上,默认使用第一个zlm开启录像,"); + log.info("[云端录像] loadMP4File时发现录像文件分布在不通的zlm上,默认使用第一个zlm开启录像"); } - mediaServerService.loadMP4File() - return null; + String mediaServerId = mediaServerIds.get(0); + MediaServer mediaServer = mediaServerService.getOne(mediaServerId); + if (mediaServer == null) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "媒体节点不存在: " + mediaServerId); + } + String buildStream = stream + "/" + date; + MediaInfo mediaInfo = mediaServerService.getMediaInfo(mediaServer, app, buildStream); + if (mediaInfo != null) { + if (callback != null) { + StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream(mediaServer, app, buildStream, mediaInfo, null); + callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); + } + return; + } + + Hook hook = Hook.getInstance(HookType.on_media_arrival, app, buildStream, mediaServerId); + subscribe.addSubscribe(hook, (hookData) -> { + StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream(mediaServer, app, buildStream, hookData.getMediaInfo(), null); + if (callback != null) { + callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); + } + }); + mediaServerService.loadMP4File(mediaServer, app, buildStream, String.format("%s/%s/%s/%s", mediaServer.getRecordPath(), app, stream, date)); } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/control/RedisRpcCloudRecordController.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/control/RedisRpcCloudRecordController.java index 516f5bfb4..ae6c5a171 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/control/RedisRpcCloudRecordController.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/control/RedisRpcCloudRecordController.java @@ -6,7 +6,7 @@ import com.genersoft.iot.vmp.conf.redis.RedisRpcConfig; import com.genersoft.iot.vmp.conf.redis.bean.RedisRpcMessage; import com.genersoft.iot.vmp.conf.redis.bean.RedisRpcRequest; import com.genersoft.iot.vmp.conf.redis.bean.RedisRpcResponse; -import com.genersoft.iot.vmp.gb28181.service.ICloudRecordService; +import com.genersoft.iot.vmp.service.ICloudRecordService; import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; import com.genersoft.iot.vmp.service.redisMsg.dto.RedisRpcController; import com.genersoft.iot.vmp.service.redisMsg.dto.RedisRpcMapping; diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java index 49dab7fbd..062710832 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java @@ -127,14 +127,17 @@ public interface CloudRecordServiceMapper { CloudRecordItem queryOne(@Param("id") Integer id); @Select(" ") - int queryCount(@Param("app") String app, @Param("stream") String stream, - @Param("startTimeStamp")Long startTimeStamp, @Param("endTimeStamp")Long endTimeStamp,); + List queryMediaServerId(@Param("app") String app, + @Param("stream") String stream, + @Param("startTimeStamp")Long startTimeStamp, + @Param("endTimeStamp")Long endTimeStamp); } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java index 6011c512e..34d83ff3c 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java @@ -1,16 +1,21 @@ package com.genersoft.iot.vmp.vmanager.cloudRecord; import com.alibaba.fastjson2.JSONArray; +import com.genersoft.iot.vmp.common.StreamInfo; +import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; -import com.genersoft.iot.vmp.gb28181.service.ICloudRecordService; import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.service.IMediaServerService; +import com.genersoft.iot.vmp.service.ICloudRecordService; import com.genersoft.iot.vmp.service.bean.CloudRecordItem; import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; +import com.genersoft.iot.vmp.service.bean.ErrorCallback; +import com.genersoft.iot.vmp.service.bean.InviteErrorCode; import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.StreamContent; +import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import com.genersoft.iot.vmp.vmanager.cloudRecord.bean.CloudRecordUrl; import com.github.pagehelper.PageInfo; import io.swagger.v3.oas.annotations.Operation; @@ -21,12 +26,15 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.async.DeferredResult; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; import java.util.ArrayList; import java.util.Calendar; import java.util.List; @@ -47,6 +55,9 @@ public class CloudRecordController { @Autowired private IMediaServerService mediaServerService; + @Autowired + private UserSetting userSetting; + @ResponseBody @GetMapping("/date/list") @@ -242,12 +253,58 @@ public class CloudRecordController { @Parameter(name = "app", description = "应用名", required = true) @Parameter(name = "stream", description = "流ID", required = true) @Parameter(name = "date", description = "日期, 例如 2025-04-10", required = true) - public StreamContent loadRecord( + public DeferredResult> loadRecord( + HttpServletRequest request, @RequestParam(required = true) String app, @RequestParam(required = true) String stream, @RequestParam(required = true) String date ) { - return cloudRecordService.loadRecord(app, stream, date); + DeferredResult> result = new DeferredResult<>(); + + result.onTimeout(()->{ + log.info("[加载录像文件超时] app={}, stream={}, date={}", app, stream, date); + WVPResult wvpResult = new WVPResult<>(); + wvpResult.setCode(ErrorCode.ERROR100.getCode()); + wvpResult.setMsg("加载录像文件超时"); + result.setResult(wvpResult); + }); + + ErrorCallback callback = (code, msg, streamInfo) -> { + + WVPResult wvpResult = new WVPResult<>(); + if (code == InviteErrorCode.SUCCESS.getCode()) { + wvpResult.setCode(ErrorCode.SUCCESS.getCode()); + wvpResult.setMsg(ErrorCode.SUCCESS.getMsg()); + + if (streamInfo != null) { + if (userSetting.getUseSourceIpAsStreamIp()) { + streamInfo=streamInfo.clone();//深拷贝 + String host; + try { + URL url=new URL(request.getRequestURL().toString()); + host=url.getHost(); + } catch (MalformedURLException e) { + host=request.getLocalAddr(); + } + streamInfo.changeStreamIp(host); + } + if (!org.springframework.util.ObjectUtils.isEmpty(streamInfo.getMediaServer().getTranscodeSuffix()) && !"null".equalsIgnoreCase(streamInfo.getMediaServer().getTranscodeSuffix())) { + streamInfo.setStream(streamInfo.getStream() + "_" + streamInfo.getMediaServer().getTranscodeSuffix()); + } + wvpResult.setData(new StreamContent(streamInfo)); + }else { + wvpResult.setCode(code); + wvpResult.setMsg(msg); + } + }else { + wvpResult.setCode(code); + wvpResult.setMsg(msg); + } + result.setResult(wvpResult); + }; + + cloudRecordService.loadRecord(app, stream, date, callback); + return result; } /************************* 以下这些接口只适合wvp和zlm部署在同一台服务器的情况,且wvp只有一个zlm节点的情况 ***************************************/ diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/log/LogController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/log/LogController.java index 050a0c5cb..209dc6fb4 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/log/LogController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/log/LogController.java @@ -1,21 +1,10 @@ package com.genersoft.iot.vmp.vmanager.log; -import ch.qos.logback.classic.Logger; -import ch.qos.logback.core.rolling.RollingFileAppender; -import com.alibaba.fastjson2.JSONArray; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; -import com.genersoft.iot.vmp.gb28181.service.ICloudRecordService; -import com.genersoft.iot.vmp.media.bean.MediaServer; -import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.ILogService; -import com.genersoft.iot.vmp.service.bean.CloudRecordItem; -import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; import com.genersoft.iot.vmp.service.bean.LogFileInfo; -import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; -import com.genersoft.iot.vmp.vmanager.cloudRecord.bean.CloudRecordUrl; -import com.github.pagehelper.PageInfo; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.security.SecurityRequirement; @@ -23,24 +12,17 @@ import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; import org.apache.commons.compress.utils.IOUtils; import org.apache.commons.lang3.ObjectUtils; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; -import java.util.ArrayList; -import java.util.Calendar; import java.util.List; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; @SuppressWarnings("rawtypes") @Tag(name = "日志文件查询接口")