diff --git a/ruoyi-modules/ruoyi-system-dataexchange/src/main/java/com/ruoyi/business/controller/InBusinessController.java b/ruoyi-modules/ruoyi-system-dataexchange/src/main/java/com/ruoyi/business/controller/InBusinessController.java index 3a547ab..c8ec77c 100644 --- a/ruoyi-modules/ruoyi-system-dataexchange/src/main/java/com/ruoyi/business/controller/InBusinessController.java +++ b/ruoyi-modules/ruoyi-system-dataexchange/src/main/java/com/ruoyi/business/controller/InBusinessController.java @@ -14,6 +14,7 @@ import com.ruoyi.business.domain.*; import com.ruoyi.business.domain.vo.*; import com.ruoyi.business.service.IAdapterService; import com.ruoyi.business.service.IServiceBusinessService; +import com.ruoyi.business.utils.FileZipUtils; import com.ruoyi.common.core.domain.vo.TransportHeader; import com.ruoyi.common.core.domain.vo.TransportRequest; import com.ruoyi.common.core.domain.vo.TransportRequestInfo; @@ -193,9 +194,17 @@ public class InBusinessController { TransportRequest request = buildRequest(ipcType, reqMap, finalToken); logger.info("线程[{}] 请求报文:\n{}", Thread.currentThread().getId(), gson.toJson(request)); - String responseJson = postRequest(request, finalUrlSuffix); - TransportResponse response = parseResponse(responseJson); - handleResponse(response, finalUrlSuffix); + if (ipcType.equals("BL1002")) { + Response response = postRequestFile(request, urlSuffix); + FileZipUtils.decryptZip(response); + // response.close(); // 处理完成后手动关闭 + } else { + String responseJson = postRequest(request, finalUrlSuffix); + logger.info("返回的response: \n{}", responseJson); + + } +// TransportResponse response = parseResponse(responseJson); +// handleResponse(response, finalUrlSuffix); return success(); } @@ -257,6 +266,24 @@ public class InBusinessController { } } + // 发送HTTP请求 + private Response postRequestFile(TransportRequest request, String urlSuffix) throws Exception { + String json = gson.toJson(request); + + RequestBody body = RequestBody.create(json, okhttp3.MediaType.get("application/json")); + Request httpRequest = new Request.Builder() + .url(API_ENDPOINT + urlSuffix) + .post(body) + .build(); + + Response response = httpClient.newCall(httpRequest).execute(); + if (!response.isSuccessful()) { + response.close(); // 失败时手动关闭 + throw new TransportException("HTTP错误: " + response.code()); + } + return response; + } + // 解析响应 private TransportResponse parseResponse(String json) { return gson.fromJson(json, TransportResponse.class); diff --git a/ruoyi-modules/ruoyi-system-dataexchange/src/main/java/com/ruoyi/business/controller/OutBusinessController.java b/ruoyi-modules/ruoyi-system-dataexchange/src/main/java/com/ruoyi/business/controller/OutBusinessController.java index 78fec03..1675b97 100644 --- a/ruoyi-modules/ruoyi-system-dataexchange/src/main/java/com/ruoyi/business/controller/OutBusinessController.java +++ b/ruoyi-modules/ruoyi-system-dataexchange/src/main/java/com/ruoyi/business/controller/OutBusinessController.java @@ -23,6 +23,7 @@ import com.ruoyi.business.service.IAdapterService; import com.ruoyi.business.service.IDatabaseService; import com.ruoyi.business.service.IServiceBusinessService; import com.ruoyi.business.service.IServiceGrantService; +import com.ruoyi.business.utils.FileZipUtils; import com.ruoyi.common.auth.entity.OauthClientDetails; import com.ruoyi.common.auth.service.OauthClientDetailsService; import com.ruoyi.common.core.domain.R; @@ -53,6 +54,7 @@ import org.springframework.web.multipart.MultipartFile; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import javax.sql.DataSource; import java.io.BufferedReader; import java.io.IOException; @@ -93,7 +95,7 @@ public class OutBusinessController { private OauthClientDetailsService oauthClientDetailsService; @PostMapping - public String outInsert(HttpServletRequest request) throws Exception { + public String outInsert(HttpServletRequest request, HttpServletResponse response) throws Exception { // if(files != null && files.length > 0 && !Objects.equals(files[0].getOriginalFilename(), "")) { // return outInsert2(request,files, jsonData); // } else { @@ -130,11 +132,11 @@ public class OutBusinessController { log.info("==================================token验证成功================================"); tokenFlag = true; } else { - log.info("==================================token验证失败2================================"); + log.info("==================================token验证失败1================================"); tokenFlag = false; } } else { - log.info("==================================token验证失败3================================"); + log.info("==================================token验证失败2================================"); transportRequest.getHeader().setReqType("1"); transportRequest.getHeader().setCode("9999"); transportRequest.getHeader().setMessage("token不存在"); @@ -149,6 +151,25 @@ public class OutBusinessController { String transportResponse = gson.toJson(transportRequest); return transportResponse; } + + String ipcType = transportRequest.getHeader().getIpcType(); + AjaxResult ajaxResult = AjaxResult.success(); + if(ipcType == null || "".equals(ipcType)) { + ajaxResult = AjaxResult.error("ipcType不能为空"); + transportRequest.getHeader().setReqType("1"); + transportRequest.getHeader().setCode("9999"); + transportRequest.getHeader().setMessage(ajaxResult.get("msg").toString()); + String transportResponse = gson.toJson(transportRequest); + return transportResponse; + } + if ("GL1001".equals(ipcType)) { + ajaxResult = AjaxResult.success("心跳检测成功"); + transportRequest.getHeader().setReqType("1"); + transportRequest.getHeader().setCode("9999"); + transportRequest.getHeader().setMessage(ajaxResult.get("msg").toString()); + String transportResponse = gson.toJson(transportRequest); + return transportResponse; + } String decryptBodyStr = ""; if (!org.springframework.util.StringUtils.isEmpty(body)) { try { @@ -158,7 +179,11 @@ public class OutBusinessController { throw new RuntimeException(e); } } - AjaxResult ajaxResult = outInsert1(transportRequest,decryptBodyStr); + if ("GL1004".equals(ipcType)) { + outFiles(decryptBodyStr,response); + return "附件获取成功"; + } + ajaxResult = outInsert1(transportRequest,decryptBodyStr,response); if (ajaxResult.isSuccess() || Integer.valueOf(200).equals(ajaxResult.get("code"))) { transportRequest.getHeader().setReqType("1"); transportRequest.getHeader().setCode("0000"); @@ -173,15 +198,9 @@ public class OutBusinessController { return transportResponse; } - private AjaxResult outInsert1(TransportRequest transportRequest, String jsonData) throws Exception{ + private AjaxResult outInsert1(TransportRequest transportRequest, String jsonData, HttpServletResponse response) throws Exception{ String ipcType = transportRequest.getHeader().getIpcType(); - if(ipcType == null || "".equals(ipcType)) { - return AjaxResult.error("ipcType不能为空"); - } - if ("GL1001".equals(ipcType)) { - return AjaxResult.success("心跳检测成功"); - } ServiceBusiness serviceBusiness = serviceBusinessService.selectServiceBusinessByOutName(ipcType+"_OUT"); // validGrant(String.valueOf(serviceBusiness.getId())); if(!BusinessServiceEnum.insert.getCode().equals(serviceBusiness.getType())) { @@ -210,8 +229,32 @@ public class OutBusinessController { final String finalReqBody = reqBody; TransportRequestInfo transportRequestInfo = JSONObject.parseObject(jsonData, TransportRequestInfo.class); Map transportMap = (Map) transportRequestInfo.getReqInfo(); - JSONArray jsonArray = (JSONArray.parseArray(String.valueOf(transportMap.get(finalReqBody)))); - log.info(jsonArray.toString()); + + //JSONArray jsonArray = (JSONArray.parseArray(String.valueOf(transportMap.get(finalReqBody)))); + //log.info(jsonArray.toString()); + // 增加JSON类型判断逻辑 + Object data = transportMap.get(finalReqBody); + String jsonStr = String.valueOf(data); + JSONArray jsonArray; + + if (StringUtils.isNotEmpty(jsonStr)) { + if (jsonStr.trim().startsWith("[")) { + jsonArray = JSONArray.parseArray(jsonStr); + } else if (jsonStr.trim().startsWith("{")) { + // 如果字段要求数组但收到对象,可以按需处理: + // 1. 返回错误:return AjaxResult.error(finalReqBody + "字段应为数组格式"); + // 2. 包装成数组 + jsonArray = new JSONArray(); + jsonArray.add(JSONObject.parseObject(jsonStr)); + } else { + return AjaxResult.error(finalReqBody + "字段格式异常,应为JSON数组或对象"); + } + } else { + return AjaxResult.error(finalReqBody + "字段不能为空"); + } + + log.info("插入的jsonArray.toString数组:"+jsonArray.toString()); + int batchSize = 50; if (jsonArray.size() > batchSize) { return AjaxResult.error("超过50条数据"); @@ -355,6 +398,51 @@ public class OutBusinessController { return AjaxResult.success("插入成功"); } + private void outFiles(String jsonData, HttpServletResponse response) throws Exception{ + String finalReqBody = "recordInfo"; + // 新增final副本用于lambda + TransportRequestInfo transportRequestInfo = JSONObject.parseObject(jsonData, TransportRequestInfo.class); + Map transportMap = (Map) transportRequestInfo.getReqInfo(); + + Object data = transportMap.get(finalReqBody); + String jsonStr = String.valueOf(data); + JSONArray jsonArray = new JSONArray(); + + if (StringUtils.isNotEmpty(jsonStr)) { + if (jsonStr.trim().startsWith("[")) { + jsonArray = JSONArray.parseArray(jsonStr); + } else if (jsonStr.trim().startsWith("{")) { + // 如果字段要求数组但收到对象,可以按需处理: + // 1. 返回错误:return AjaxResult.error(finalReqBody + "字段应为数组格式"); + // 2. 包装成数组 + jsonArray = new JSONArray(); + jsonArray.add(JSONObject.parseObject(jsonStr)); + } + } + + log.info("jsonArray.toString数组:"+jsonArray.toString()); + + Map fileInfo = new HashMap<>(); + // 循环处理JSONArray中的每个JSONObject + for (int i = 0; i < jsonArray.size(); i++) { + final int idx = i; // 创建final副本解决lambda表达式变量捕获问题 + JSONObject jsonObject = jsonArray.getJSONObject(idx); + for (String key : jsonObject.keySet()) { + Object value = jsonObject.get(key); + if (key.contains("Id")) { + fileInfo.put("Id", String.valueOf(value)); + } + if (key.contains("Name")) { + fileInfo.put("Name", String.valueOf(value)); + } + if (key.contains("Type")) { + fileInfo.put("Type", String.valueOf(value)); + } + } + } + FileZipUtils.getEncryptZip(response,fileInfo); + } + /** * 接口权限 * @param businessId 业务id @@ -719,12 +807,15 @@ public class OutBusinessController { // 设置参数 for (String key : json.keySet()) { if (resFieldSet.contains(FebsUtil.camelToUnderscore(key))) { - // 检查是否是 JsonArray类型比如qxhydsxx 字段,确保它是一个有效的 JSON 字符串 - if (json.get(key) instanceof JSONArray) { - // 将 JSON 对象转换为字符串 - ps.setString(index++, json.getJSONArray(key).toString()); + Object value = json.get(key); + if (value instanceof JSONArray) { + ps.setString(index++, ((JSONArray) value).toJSONString()); + } else if (value instanceof JSONObject) { + ps.setString(index++, ((JSONObject) value).toJSONString()); + } else if (value != null) { + ps.setString(index++, value.toString()); } else { - ps.setObject(index++, json.get(key)); + ps.setNull(index++, Types.VARCHAR); } } } diff --git a/ruoyi-modules/ruoyi-system-dataexchange/src/main/java/com/ruoyi/business/utils/FileZipUtils.java b/ruoyi-modules/ruoyi-system-dataexchange/src/main/java/com/ruoyi/business/utils/FileZipUtils.java new file mode 100644 index 0000000..f761bad --- /dev/null +++ b/ruoyi-modules/ruoyi-system-dataexchange/src/main/java/com/ruoyi/business/utils/FileZipUtils.java @@ -0,0 +1,130 @@ +package com.ruoyi.business.utils; + +import net.lingala.zip4j.io.inputstream.ZipInputStream; +import net.lingala.zip4j.io.outputstream.ZipOutputStream; +import net.lingala.zip4j.model.LocalFileHeader; +import net.lingala.zip4j.model.ZipParameters; +import net.lingala.zip4j.model.enums.CompressionLevel; +import net.lingala.zip4j.model.enums.CompressionMethod; +import net.lingala.zip4j.model.enums.EncryptionMethod; +import okhttp3.Response; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.net.URLEncoder; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class FileZipUtils { + + public static void decryptZip(Response response) throws Exception { + Path storageDir = Paths.get( + System.getProperty("user.dir"), // 获取项目根目录 + "ruoyi-modules/ruoyi-system-dataexchange/src/main/resources/filesIn" // 指定存储目录 + ).toAbsolutePath(); + // 确保目录存在 + Files.createDirectories(storageDir); + // 修改为项目根目录下的存储路径 + System.out.println("Final storage path: " + storageDir.toAbsolutePath()); + // System.out.println("响应体body: " + response.body().string()); + + // 确保目录存在 + Files.createDirectories(storageDir); + try (InputStream responseInputStream = response.body().byteStream()) { + // 2. 设置ZIP密码 + String password = "QLdQIASYMlT9SUUg"; + List extractedContents = new ArrayList<>(); + try (ZipInputStream zipInputStream = new ZipInputStream(responseInputStream, password.toCharArray())) { + LocalFileHeader fileHeader; + byte[] buffer = new byte[8192]; // 8KB 缓冲区 + // 遍历 ZIP 中的每个文件 + while ((fileHeader = zipInputStream.getNextEntry()) != null) { + String fileName = fileHeader.getFileName().split("_")[1]; + Path outputPath = storageDir.resolve(fileName); + // 确保父目录存在 + Files.createDirectories(outputPath.getParent()); + try (OutputStream outputStream = Files.newOutputStream(outputPath)) { + int bytesRead; + while ((bytesRead = zipInputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + } + } + } + } + } + + + public static void getEncryptZip(HttpServletResponse response, Map fileInfo) throws IOException { + // 1. 定义要下载的图片URL列表 + List imageUrls = new ArrayList<>(); + Path storageDir = Paths.get( + System.getProperty("user.dir"), // 获取项目根目录 + "ruoyi-modules\\ruoyi-system-dataexchange\\src\\main\\resources\\filesOut" // 改用Windows路径分隔符 + ).toAbsolutePath(); + imageUrls.add(storageDir.resolve(fileInfo.get("Name")).toString()); + // imageUrls.add(storageDir.resolve("1512b987-6954-4533-8154-e8b8bcce5a6e.png").toString()); + // 2. 设置ZIP密码 + String password = "8iot1blDJgNK36Do"; + setResHeader(response, "MaterialFile-"+fileInfo.get("Id")+".zip"); + // 3. 创建ZIP输出流(直接写入HTTP响应流) + try (ServletOutputStream outputStream = response.getOutputStream()) { + try (ZipOutputStream zipOut = new ZipOutputStream(outputStream, password.toCharArray())) { + for (String imageUrl : imageUrls) { + try (FileInputStream fileInputStream = new FileInputStream(new File(imageUrl))) { + addFileToZip(zipOut, fileInputStream, fileInfo.get("Id")+"_"+imageUrl.substring(imageUrl.lastIndexOf("\\") + 1)); + } + } + } + } + } + + /** + * @Description: 设置响应头 + * @data:[response,zipFileName 文件名没有后缀] + * @Author: J + * @Date: 2025-03-26 13:57:13 + */ + public static void setResHeader(HttpServletResponse response, String zipFileName) { + try { + response.setContentType("application/zip"); + response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(zipFileName + ".zip", "UTF-8")); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + /** + * @Description: 将图片下载并打包成ZIP文件,写入输出流 + * @data:[zipOut zip输出流, imageInputStream 单个文件流, fileName 单个文件名称带后缀] + * @Author: J + * @Date: 2025-03-26 13:55:10 + */ + public static void addFileToZip(ZipOutputStream zipOut, InputStream imageInputStream, String fileName) throws IOException { + ZipParameters zipParams = new ZipParameters(); + zipParams.setCompressionMethod(CompressionMethod.DEFLATE); // 使用 DEFLATE 算法 + zipParams.setCompressionLevel(CompressionLevel.HIGHER); // 设置压缩级别 + zipParams.setFileNameInZip(fileName); + zipParams.setEncryptFiles(true); + zipParams.setEncryptionMethod(EncryptionMethod.AES); + // 3. 开始写入ZIP条目 + zipOut.putNextEntry(zipParams); + // 4. 下载图片并流式写入ZIP + try (InputStream imageStream = imageInputStream) { + int bytesRead; + byte[] buffer = new byte[8192]; // 8KB缓冲区 + while ((bytesRead = imageStream.read(buffer)) != -1) { + zipOut.write(buffer, 0, bytesRead); + } + } + // 5. 关闭当前条目 + zipOut.closeEntry(); + } + + +} diff --git a/ruoyi-modules/ruoyi-system-dataexchange/src/main/resources/filesIn/0555bede11ac9d64379e9eced17eb91f.jpg b/ruoyi-modules/ruoyi-system-dataexchange/src/main/resources/filesIn/0555bede11ac9d64379e9eced17eb91f.jpg new file mode 100644 index 0000000..dcc7d22 Binary files /dev/null and b/ruoyi-modules/ruoyi-system-dataexchange/src/main/resources/filesIn/0555bede11ac9d64379e9eced17eb91f.jpg differ diff --git a/ruoyi-modules/ruoyi-system-dataexchange/src/main/resources/filesIn/JT9999992025051710003416_0555bede11ac9d64379e9eced17eb91f.jpg b/ruoyi-modules/ruoyi-system-dataexchange/src/main/resources/filesIn/JT9999992025051710003416_0555bede11ac9d64379e9eced17eb91f.jpg new file mode 100644 index 0000000..dcc7d22 Binary files /dev/null and b/ruoyi-modules/ruoyi-system-dataexchange/src/main/resources/filesIn/JT9999992025051710003416_0555bede11ac9d64379e9eced17eb91f.jpg differ diff --git a/ruoyi-modules/ruoyi-system-dataexchange/src/main/resources/filesOut/0555bede11ac9d64379e9eced17eb999.jpg b/ruoyi-modules/ruoyi-system-dataexchange/src/main/resources/filesOut/0555bede11ac9d64379e9eced17eb999.jpg new file mode 100644 index 0000000..9fd037d Binary files /dev/null and b/ruoyi-modules/ruoyi-system-dataexchange/src/main/resources/filesOut/0555bede11ac9d64379e9eced17eb999.jpg differ diff --git a/src/main/resources/filesIn/JT9999992025051710003416_0555bede11ac9d64379e9eced17eb91f.jpg b/src/main/resources/filesIn/JT9999992025051710003416_0555bede11ac9d64379e9eced17eb91f.jpg new file mode 100644 index 0000000..dcc7d22 Binary files /dev/null and b/src/main/resources/filesIn/JT9999992025051710003416_0555bede11ac9d64379e9eced17eb91f.jpg differ