Quellcode durchsuchen

feat(protocol): 实现协议文件下载功能

- 修改控制器方法签名,支持 HttpServletResponse 参数
- 更新服务接口,移除返回值,新增响应流参数
- 实现协议文件流式下载逻辑
- 添加文件名编码与 Content-Type 推断
- 设置响应头支持附件下载
- 增加输入输出流异常处理与资源释放
- 调整删除逻辑,使用物理删除替代逻辑删除
fcw vor 5 Tagen
Ursprung
Commit
d1c72598cc

+ 12 - 6
alien-store/src/main/java/shop/alien/store/controller/ProtocolManagementController.java

@@ -11,6 +11,9 @@ import shop.alien.entity.result.R;
 import shop.alien.entity.store.ProtocolManagement;
 import shop.alien.store.service.ProtocolManagementService;
 
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
 /**
  * 协议管理表 前端控制器
  *
@@ -58,18 +61,21 @@ public class ProtocolManagementController {
             @ApiImplicitParam(name = "id", value = "协议ID", dataType = "Integer", paramType = "query", required = true)
     })
     @GetMapping("/getById")
-    public R<ProtocolManagement> getById(@RequestParam("id") Integer id) {
+    public void getById(@RequestParam("id") Integer id, HttpServletResponse response) throws IOException {
         log.info("ProtocolManagementController.getById?id={}", id);
-        
+
         try {
-            ProtocolManagement protocol = protocolManagementService.getProtocolById(id);
-            return R.data(protocol);
+            protocolManagementService.getProtocolById(id, response);
         } catch (IllegalArgumentException e) {
             log.error("查询协议详情失败", e);
-            return R.fail(e.getMessage());
+            if (!response.isCommitted()) {
+                response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
+            }
         } catch (Exception e) {
             log.error("查询协议详情失败", e);
-            return R.fail("查询失败: " + e.getMessage());
+            if (!response.isCommitted()) {
+                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "查询失败: " + e.getMessage());
+            }
         }
     }
 

+ 2 - 2
alien-store/src/main/java/shop/alien/store/service/ProtocolManagementService.java

@@ -29,9 +29,9 @@ public interface ProtocolManagementService extends IService<ProtocolManagement>
      * 根据ID查询协议详情
      *
      * @param id 协议ID
-     * @return ProtocolManagement
+     * @param response 响应流
      */
-    ProtocolManagement getProtocolById(Integer id);
+    void getProtocolById(Integer id, javax.servlet.http.HttpServletResponse response);
 
     /**
      * 新增协议

+ 79 - 8
alien-store/src/main/java/shop/alien/store/service/impl/ProtocolManagementServiceImpl.java

@@ -19,6 +19,14 @@ import shop.alien.util.common.RandomCreateUtil;
 import shop.alien.util.ali.AliOSSUtil;
 import shop.alien.util.file.FileUtil;
 
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
@@ -67,20 +75,84 @@ public class ProtocolManagementServiceImpl extends ServiceImpl<ProtocolManagemen
     }
 
     @Override
-    public ProtocolManagement getProtocolById(Integer id) {
+    public void getProtocolById(Integer id, HttpServletResponse response) {
         log.info("协议管理-查询详情, id: {}", id);
-        
+
         if (id == null) {
             throw new IllegalArgumentException("协议ID不能为空");
         }
-        
+
         ProtocolManagement protocol = protocolManagementMapper.selectById(id);
-        
+
         if (protocol == null) {
             throw new IllegalArgumentException("协议不存在");
         }
-        
-        return protocol;
+
+        String protocolUrl = protocol.getProtocolFilePath();
+        if (StringUtils.isBlank(protocolUrl)) {
+            throw new IllegalArgumentException("协议文件路径不存在");
+        }
+
+        InputStream inputStream = null;
+        OutputStream outputStream = null;
+        try {
+            URL url = new URL(protocolUrl);
+            URLConnection connection = url.openConnection();
+            connection.setConnectTimeout(5000);
+            connection.setReadTimeout(10000);
+
+            // 推断文件名与Content-Type
+            String path = url.getPath();
+            int lastSlash = path.lastIndexOf('/');
+            String fileName = lastSlash >= 0 ? path.substring(lastSlash + 1) : "protocol.html";
+            if (fileName.contains("?")) {
+                fileName = fileName.substring(0, fileName.indexOf('?'));
+            }
+            if (StringUtils.isBlank(fileName)) {
+                fileName = "protocol.html";
+            }
+            String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()).replaceAll("\\+", "%20");
+
+            String contentType = connection.getContentType();
+            if (StringUtils.isBlank(contentType)) {
+                // 默认按照html返回,兜底八进制流
+                contentType = protocolUrl.toLowerCase().endsWith(".html")
+                        ? "text/html;charset=utf-8"
+                        : "application/octet-stream";
+            }
+
+            response.reset();
+            response.setCharacterEncoding("utf-8");
+            response.setContentType(contentType);
+            response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + encodedFileName);
+
+            inputStream = connection.getInputStream();
+            outputStream = response.getOutputStream();
+            byte[] buffer = new byte[8192];
+            int len;
+            while ((len = inputStream.read(buffer)) != -1) {
+                outputStream.write(buffer, 0, len);
+            }
+            outputStream.flush();
+        } catch (IOException e) {
+            log.error("协议管理-协议文件流输出失败, id: {}, url: {}", id, protocolUrl, e);
+            throw new RuntimeException("协议文件下载失败");
+        } finally {
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                } catch (IOException e) {
+                    log.error("关闭协议文件输入流失败", e);
+                }
+            }
+            if (outputStream != null) {
+                try {
+                    outputStream.close();
+                } catch (IOException e) {
+                    log.error("关闭协议文件输出流失败", e);
+                }
+            }
+        }
     }
 
     @Override
@@ -175,10 +247,9 @@ public class ProtocolManagementServiceImpl extends ServiceImpl<ProtocolManagemen
         if (protocol == null) {
             throw new IllegalArgumentException("协议不存在");
         }
-        protocol.setDeleteFlag(1);
         
         // 逻辑删除
-        int result = protocolManagementMapper.updateById(protocol);
+        int result = protocolManagementMapper.deleteById(protocol);
         log.info("协议管理-删除, 结果: {}", result > 0 ? "成功" : "失败");
         
         return result > 0;