From a9f7feead31f9b5449b6209accaf436e7ab59df7 Mon Sep 17 00:00:00 2001 From: zzs Date: Fri, 27 Sep 2024 18:33:21 +0800 Subject: [PATCH] wip:sync image --- .../crm/controller/crm/ProxyController.java | 19 ++- .../crm/module/crm/service/ImageService.java | 56 ++++++++ .../crm/module/crm/service/ProxyService.java | 124 +++++++++++++++--- 3 files changed, 179 insertions(+), 20 deletions(-) create mode 100644 ensign-module-crm/ensign-module-crm-biz/src/main/java/com/ensign/crm/module/crm/service/ImageService.java diff --git a/ensign-module-crm/ensign-module-crm-biz/src/main/java/com/ensign/crm/module/crm/controller/crm/ProxyController.java b/ensign-module-crm/ensign-module-crm-biz/src/main/java/com/ensign/crm/module/crm/controller/crm/ProxyController.java index c0d26f3..be56b8c 100644 --- a/ensign-module-crm/ensign-module-crm-biz/src/main/java/com/ensign/crm/module/crm/controller/crm/ProxyController.java +++ b/ensign-module-crm/ensign-module-crm-biz/src/main/java/com/ensign/crm/module/crm/controller/crm/ProxyController.java @@ -1,5 +1,7 @@ package com.ensign.crm.module.crm.controller.crm; +import com.ensign.crm.framework.common.pojo.CommonResult; +import com.ensign.crm.module.crm.exception.AllKingdeeException; import com.ensign.crm.module.crm.service.ProxyService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -8,8 +10,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -39,4 +41,17 @@ public class ProxyController { proxyService.doProxy(request, response); } + @PostMapping(value = "/file/do/**") + @Operation(summary = "转发接口_文件") + @PreAuthorize("@ss.hasPermission('crm:proxy:all')") + public CommonResult proxyFile(HttpServletRequest request, MultipartFile file) throws IOException, URISyntaxException, AllKingdeeException { + return CommonResult.success(proxyService.doProxyFile(request, file)); + } + + @GetMapping("/file/read/do") + @PreAuthorize("@ss.hasPermission('crm:proxy:all')") + @Operation(summary = "获取图片") + public byte[] proxyRead(@RequestParam String fileId, @RequestParam boolean isTemp) throws IOException, URISyntaxException, AllKingdeeException { + return proxyService.dpGetImage(fileId, isTemp); + } } diff --git a/ensign-module-crm/ensign-module-crm-biz/src/main/java/com/ensign/crm/module/crm/service/ImageService.java b/ensign-module-crm/ensign-module-crm-biz/src/main/java/com/ensign/crm/module/crm/service/ImageService.java new file mode 100644 index 0000000..aee81c7 --- /dev/null +++ b/ensign-module-crm/ensign-module-crm-biz/src/main/java/com/ensign/crm/module/crm/service/ImageService.java @@ -0,0 +1,56 @@ +package com.ensign.crm.module.crm.service; + +import lombok.extern.slf4j.Slf4j; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +/** + * @Description: TODO + * @Date: 2024/9/27 15:09 + * @Created: by ZZSLL + */ + + +@Service +@Slf4j +public class ImageService { + + @Resource + private RedisTemplate redisTemplate; + + private final String CACHE_PREFIX = "kingdee:temp_file"; + + public byte[] downloadImage(String imageUrl) throws IOException { + CloseableHttpClient httpClient = HttpClients.createDefault(); + HttpGet httpGet = new HttpGet(imageUrl); + CloseableHttpResponse response = httpClient.execute(httpGet); + + try { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + response.getEntity().writeTo(outputStream); + return outputStream.toByteArray(); + } finally { + response.close(); + httpClient.close(); + } + } + + public void saveImage(String key, byte[] imageData) { + redisTemplate.opsForValue().set(CACHE_PREFIX + key, imageData, 2, TimeUnit.HOURS); + } + + public byte[] getImage(String key) { + return redisTemplate.opsForValue().get(CACHE_PREFIX + key); + } +} diff --git a/ensign-module-crm/ensign-module-crm-biz/src/main/java/com/ensign/crm/module/crm/service/ProxyService.java b/ensign-module-crm/ensign-module-crm-biz/src/main/java/com/ensign/crm/module/crm/service/ProxyService.java index 7e7fd3d..5af1462 100644 --- a/ensign-module-crm/ensign-module-crm-biz/src/main/java/com/ensign/crm/module/crm/service/ProxyService.java +++ b/ensign-module-crm/ensign-module-crm-biz/src/main/java/com/ensign/crm/module/crm/service/ProxyService.java @@ -14,9 +14,13 @@ import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.methods.RequestBuilder; import org.apache.http.entity.StringEntity; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.FileBody; +import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.http.HttpMethod; @@ -25,10 +29,13 @@ import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.stereotype.Service; import org.springframework.util.StreamUtils; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -68,12 +75,34 @@ public class ProxyService { @Resource private RedisTemplate redisTemplate; + @Autowired + private ImageService imageService; + public void doProxy(HttpServletRequest request, HttpServletResponse response) throws IOException, URISyntaxException { URI uri = new URI(request.getRequestURI()); String path = uri.getPath(); String query = request.getQueryString(); String target = initBasePath() + path.replace("/crm-api/proxy/do", ""); + String accessToken; + try { + accessToken = initAccessToken(); + + log.info("Header: access_token: {}", accessToken); + } catch (AllKingdeeException e) { + log.error("获取accessToken时失败:{}", e.getMessage()); + log.info("================request kingdee end================"); + response.setStatus(HttpServletResponse.SC_OK); + response.setContentType("application/json"); + response.setCharacterEncoding("UTF-8"); + Map body = new HashMap<>(); + body.put("status", false); + body.put("message", e.getMessage()); + response.getWriter().println(JSONUtil.toJsonStr(body)); + response.getWriter().flush(); + return; + } + if (query != null && !query.isEmpty() && !query.equals("null")) { target = target + "?" + query; } @@ -102,25 +131,17 @@ public class ProxyService { } log.info("Header: {}: {}", headerName, arr); delegate.getHeaders().addAll(headerName, arr); - } - try { - String accessToken = initAccessToken(); delegate.getHeaders().add("access_token", accessToken); - log.info("Header: access_token: {}", accessToken); - } catch (AllKingdeeException e) { - log.error("获取accessToken时失败:{}", e.getMessage()); - log.info("================request kingdee end================"); - response.setStatus(HttpServletResponse.SC_OK); - response.setContentType("application/json"); - response.setCharacterEncoding("UTF-8"); - Map body = new HashMap<>(); - body.put("status", false); - body.put("message", e.getMessage()); - response.getWriter().println(JSONUtil.toJsonStr(body)); - response.getWriter().flush(); - return; } - StreamUtils.copy(request.getInputStream(), delegate.getBody()); + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = request.getInputStream().read(buffer)) != -1) { + byteArrayOutputStream.write(buffer, 0, bytesRead); + } + byte[] bytes = byteArrayOutputStream.toByteArray(); + + delegate.getBody().write(bytes); // 执行远程调用 ClientHttpResponse clientHttpResponse = delegate.execute(); log.info("Response Status: {}", clientHttpResponse.getStatusCode().value()); @@ -137,7 +158,60 @@ public class ProxyService { StreamUtils.copy(clientHttpResponse.getBody(), response.getOutputStream()); } - public com.alibaba.fastjson.JSONObject doRequest(String endpoint, String methodName, Map body, Map header) throws AllKingdeeException, IOException, URISyntaxException { + public String doProxyFile(HttpServletRequest request, MultipartFile file) throws IOException, URISyntaxException, AllKingdeeException { + URI uri = new URI(request.getRequestURI()); + String path = uri.getPath(); + String target = initBasePath() + path.replace("/crm-api/proxy/file/do", ""); + String accessToken = initAccessToken(); + target = target + "?access_token=" + accessToken; + URI newUri = new URI(target); + CloseableHttpClient httpClient = HttpClients.createDefault(); + HttpPost httpPost = new HttpPost(newUri); + MultipartEntityBuilder builder = MultipartEntityBuilder.create(); + builder.addPart("file", new FileBody(transferToFile(file))); + HttpEntity multipartEntity = builder.build(); + httpPost.setEntity(multipartEntity); + HttpResponse kResponse = httpClient.execute(httpPost); + HttpEntity entity = kResponse.getEntity(); + String jsonStr = EntityUtils.toString(entity, "UTF-8").trim(); + JSONObject jsonObject = JSON.parseObject(jsonStr); + if (jsonObject.containsKey("url")) { + String url = jsonObject.getString("url"); + String fileId = extractFileId(url); + String downloadUrl = url + "&access_token=" + initAccessToken(); + byte[] bytes = imageService.downloadImage(downloadUrl); + imageService.saveImage(fileId, bytes); + return doConvertFileUrl(fileId, true); + } + return null; + } + + private String extractFileId(String url) throws AllKingdeeException, URISyntaxException { + URI uri = new URI(url); + String query = uri.getQuery(); + if (query != null) { + String[] queryParams = query.split("&"); + for (String param : queryParams) { + String[] keyValue = param.split("="); + if (keyValue.length == 2 && keyValue[0].equals("id")) { + return keyValue[1]; + } + } + } + throw new AllKingdeeException("获取file失败"); + } + + public File transferToFile(MultipartFile multipartFile) throws IOException { + String originalFilename = multipartFile.getOriginalFilename(); + assert originalFilename != null; + String[] filename = originalFilename.split("\\."); + File file = File.createTempFile(filename[0], "." + filename[1]); + multipartFile.transferTo(file); + file.deleteOnExit(); + return file; + } + + public JSONObject doRequest(String endpoint, String methodName, Map body, Map header) throws AllKingdeeException, IOException, URISyntaxException { log.info("================request kingdee start================"); HttpClient httpClient = HttpClients.createDefault(); @@ -296,4 +370,18 @@ public class ProxyService { return ""; } + + public String doConvertFileUrl(String fileId, boolean isTemp) { + if (isTemp) { + return "/crm-api/proxy/file/read/do?fileId=" + fileId + "&isTemp=true"; + } + return ""; + } + + public byte[] dpGetImage(String fileId, boolean isTemp) { + if (isTemp) { + return imageService.getImage(fileId); + } + return null; + } }