From aae3307eb976f7d185cbf96b2a18fa2110f90b2d Mon Sep 17 00:00:00 2001 From: huliyong <2783385703@qq.com> Date: Mon, 17 Mar 2025 17:20:38 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=8E=B7=E5=8F=96=E4=B8=AA?= =?UTF-8?q?=E4=BA=BA=E4=BA=8C=E7=BB=B4=E7=A0=81=E5=A4=AA=E9=95=BF=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E3=80=81=E8=83=8C=E6=99=AF=E6=B2=A1=E6=9C=89=E4=BA=8C?= =?UTF-8?q?=E7=BB=B4=E7=A0=81=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 15 ++ .../jeecg/api/controller/AppletInfoController.java | 7 +- .../org/jeecg/api/service/AppletIndexService.java | 3 + .../api/service/impl/AppletIndexServiceImpl.java | 270 ++++++++++++--------- 4 files changed, 181 insertions(+), 114 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d1bd161 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +.idea +package-lock.json +node_modules/ +unpackage/ +.hbuilderx +.vite +target \ No newline at end of file diff --git a/module-common/src/main/java/org/jeecg/api/controller/AppletInfoController.java b/module-common/src/main/java/org/jeecg/api/controller/AppletInfoController.java index 34ae3bc..c0b503d 100644 --- a/module-common/src/main/java/org/jeecg/api/controller/AppletInfoController.java +++ b/module-common/src/main/java/org/jeecg/api/controller/AppletInfoController.java @@ -8,6 +8,7 @@ import org.jeecg.api.service.AppletIndexService; import org.jeecg.common.api.vo.Result; import org.jeecg.modules.commonAddress.entity.CommonAddress; import org.jeecg.modules.commonFack.entity.CommonFack; +import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @@ -79,9 +80,9 @@ public class AppletInfoController { //获取个人邀请码 @ApiOperation(value="获取个人邀请码", notes="获取个人邀请码") - @GetMapping(value = "/getInviteCode") - public Result getInviteCode(@RequestHeader("X-Access-Token") String token){ - return apiRiceService.getInviteCode(token); + @GetMapping(value = "/getInviteCode", produces = MediaType.IMAGE_PNG_VALUE) + public byte[] getInviteCode(String token){ + return apiRiceService.getInviteCode2(token); } //获取购物车信息列表带分页 diff --git a/module-common/src/main/java/org/jeecg/api/service/AppletIndexService.java b/module-common/src/main/java/org/jeecg/api/service/AppletIndexService.java index f62f45b..1f2dc90 100644 --- a/module-common/src/main/java/org/jeecg/api/service/AppletIndexService.java +++ b/module-common/src/main/java/org/jeecg/api/service/AppletIndexService.java @@ -98,6 +98,9 @@ public interface AppletIndexService { //获取个人邀请码 Result getInviteCode(String token); + //获取个人邀请码 + byte[] getInviteCode2(String token); + //获取相关介绍 Result getInfoIntroduce(String type); diff --git a/module-common/src/main/java/org/jeecg/api/service/impl/AppletIndexServiceImpl.java b/module-common/src/main/java/org/jeecg/api/service/impl/AppletIndexServiceImpl.java index 8c5dcbc..9d7d829 100644 --- a/module-common/src/main/java/org/jeecg/api/service/impl/AppletIndexServiceImpl.java +++ b/module-common/src/main/java/org/jeecg/api/service/impl/AppletIndexServiceImpl.java @@ -19,6 +19,7 @@ import org.jeecg.api.bean.PageBean; import org.jeecg.api.bean.WxQrCodeVo; import org.jeecg.api.service.AppletIndexService; import org.jeecg.common.api.vo.Result; +import org.jeecg.common.util.RedisUtil; import org.jeecg.config.shiro.ShiroRealm; import org.jeecg.modules.commonAddress.entity.CommonAddress; import org.jeecg.modules.commonAddress.service.ICommonAddressService; @@ -89,6 +90,7 @@ import java.awt.image.BufferedImage; import java.io.*; import java.math.BigDecimal; import java.net.URL; +import java.nio.file.Files; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.temporal.ChronoUnit; @@ -162,6 +164,8 @@ public class AppletIndexServiceImpl implements AppletIndexService { @Autowired private ICommonordergiveService commonordergiveService; + @Autowired + private RedisUtil redisUtil; @@ -1107,54 +1111,18 @@ public class AppletIndexServiceImpl implements AppletIndexService { ResponseEntity entity = rest.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]); byte[] result = entity.getBody(); - inputStream = new ByteArrayInputStream(result); - String tempSave = codeImg; - String filePath = tempSave; - - file = new File(filePath); - if (!file.exists()) { - file.createNewFile(); - } - outputStream = new FileOutputStream(file); - int len = 0; - byte[] buf = new byte[1024]; - while ((len = inputStream.read(buf, 0, 1024)) != -1) { - outputStream.write(buf, 0, len); - } - outputStream.flush(); - /** - * 将文件上传至阿里云 - */ - DiskFileItemFactory factory = new DiskFileItemFactory(16, null); - FileItem item = factory.createItem("File", "text/plain", true, file.getName()); - int bytesRead = 0; - byte[] buffer = new byte[8192]; - try { - FileInputStream fis = new FileInputStream(file); - OutputStream os = item.getOutputStream(); - while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) { - os.write(buffer, 0, bytesRead); - } - os.close(); - fis.close(); - } catch (IOException e) { - e.printStackTrace(); - } - MultipartFile mf = new CommonsMultipartFile(item); //返回图片下载地址 WxQrCodeVo wxCodeVo = new WxQrCodeVo(); - this.uploadAliYunOss(mf); - CommonConfig image_go_url = commonConfigService.lambdaQuery() .eq(CommonConfig::getKeyName, "image_go_url") .one(); - String qrCodeImageUrl = image_go_url.getKeyContent()+this.uploadAliYunOss(mf); + String qrCodeImageUrl = image_go_url.getKeyContent()+ this.uploadAliYunOss(result, file.getName()); String backgroundImageUrl = qr_code.getKeyContent(); String outputFilePath = "combined_image_code"; - String s = this.generateAndCombineImagesFromUrl(qrCodeImageUrl, backgroundImageUrl, outputFilePath); - wxCodeVo.setUrl(s); +// String s = this.generateAndCombineImagesFromUrl2(qrCodeImageUrl, backgroundImageUrl, outputFilePath); + wxCodeVo.setUrl(null); wxCodeVo.setName("陌美人珠宝欢迎您"); @@ -1187,84 +1155,152 @@ public class AppletIndexServiceImpl implements AppletIndexService { return null; } + //获取推广二维码 2 + @Override + public byte[] getInviteCode2(String token){ + HanHaiMember member = shiroRealm.checkUserTokenIsEffectHanHaiOpenId(token); + + // 获取环境配置 + CommonConfig vsion = commonConfigService.lambdaQuery() + .eq(CommonConfig::getKeyName, "v_sion") + .one(); + Integer vsionStr = Integer.parseInt(vsion.getKeyContent()); + String trial = "release"; + if(vsionStr == 0){ + trial= "release"; + }else if(vsionStr == 1){ + trial= "trial"; + }else{ + trial= "develop"; + } + + // 获取必要的配置信息 + CommonConfig xcxSharePage = commonConfigService.lambdaQuery() + .eq(CommonConfig::getKeyName, "xcxSharePage") + .one(); + + CommonConfig oneImage = commonConfigService.lambdaQuery() + .eq(CommonConfig::getKeyName, "codeImg") + .one(); + + CommonConfig qr_code = commonConfigService.lambdaQuery() + .eq(CommonConfig::getKeyName, "qr_code") + .one(); + + CommonConfig image_go_url = commonConfigService.lambdaQuery() + .eq(CommonConfig::getKeyName, "image_go_url") + .one(); + + String backgroundImageUrl = qr_code.getKeyContent(); + + // 尝试从缓存获取二维码 + String cacheKey = "CodeImage::" + trial + member.getId(); + WxQrCodeVo wxCodeVo = new WxQrCodeVo(); + wxCodeVo.setName("陌美人珠宝欢迎您"); + // 如果启用了Redis缓存,可以取消下面注释 +// String cachedQrCode = (String) redisUtil.get(cacheKey); +// if(cachedQrCode != null){ +// String combinedImageUrl = this.generateAndCombineImagesFromUrl(cachedQrCode, backgroundImageUrl, "combined_image_code"); +// wxCodeVo.setUrl(combinedImageUrl); +// return Result.OK(wxCodeVo); +// } - public String generateAndCombineImagesFromUrl(String qrCodeImageUrl, String backgroundUrl, String outputFilePath) { + try { + + // 准备微信API请求参数 + String key = "shareId=" + member.getId(); + Map param = new HashMap<>(); + param.put("path", xcxSharePage.getKeyContent() + "?" + key); + param.put("scene", member.getId()); + param.put("width", 150); + param.put("auto_color", false); + param.put("env_version", trial); + +// Map line_color = new HashMap<>(); +// line_color.put("r", 0); +// line_color.put("g", 0); +// line_color.put("b", 0); +// param.put("line_color", line_color); + + + param.put("is_hyaline", true); + + // 获取微信小程序码 + String accessToken = this.getAccessToken(); + String url = "https://api.weixin.qq.com/wxa/getwxacode?access_token=" + accessToken; + + // 请求微信API获取二维码图片数据 + RestTemplate rest = new RestTemplate(); + MultiValueMap headers = new LinkedMultiValueMap<>(); + org.springframework.http.HttpEntity requestEntity = new org.springframework.http.HttpEntity(JSON.toJSONString(param), headers); + ResponseEntity entity = rest.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]); + byte[] qrCodeBytes = entity.getBody(); + + // 直接将二维码图片转为MultipartFile,避免写入临时文件 +// MultipartFile qrCodeFile = createMultipartFile(qrCodeBytes, "qrcode.jpg"); + + // 上传二维码到阿里云并获取URL +// String qrCodeImageUrl = image_go_url.getKeyContent() + this.uploadAliYunOss(qrCodeFile); + + // 合并图片并上传 +// String combinedImageUrl = this.generateAndCombineImagesFromUrl2(qrCodeBytes, backgroundImageUrl); + + // 设置返回数据 + + // 如果启用了Redis缓存,可以取消下面注释 + //redisUtil.set(cacheKey, qrCodeImageUrl, 3600); // 缓存一小时 + + return this.generateAndCombineImagesFromUrl2(qrCodeBytes, backgroundImageUrl); + } catch (Exception e) { + e.printStackTrace(); + + return null; + } + } + + public byte[] generateAndCombineImagesFromUrl2(byte[] qrCodeImageByte, String backgroundUrl) { File file = null; try { - // 从URL加载小程序码图像 - URL qrCodeUrl = new URL(qrCodeImageUrl); - BufferedImage qrCodeImage = ImageIO.read(qrCodeUrl); + // 从字节数组加载小程序码图像 + BufferedImage qrCodeImage = ImageIO.read(new ByteArrayInputStream(qrCodeImageByte)); // 从URL加载背景图像 URL backgroundImageUrl = new URL(backgroundUrl); BufferedImage backgroundImage = ImageIO.read(backgroundImageUrl); // 创建一个新的BufferedImage来保存合并后的图像 - BufferedImage combinedImage = new BufferedImage(backgroundImage.getWidth(), backgroundImage.getHeight(), BufferedImage.TYPE_INT_ARGB); - Graphics2D g2d = combinedImage.createGraphics(); + Graphics2D g2d = backgroundImage.createGraphics(); - // 绘制背景图像 - g2d.drawImage(backgroundImage, 0, 0, null); + int wh = backgroundImage.getWidth() / 3; // 计算小程序码放置的位置(这里以中心位置为例) - int qrCodeX = (backgroundImage.getWidth() - qrCodeImage.getWidth()) / 2; - int qrCodeY = (backgroundImage.getHeight() - qrCodeImage.getHeight()) / 2; -// -// int backgroundHeight = backgroundImage.getHeight(); -// int qrCodeHeight = qrCodeImage.getHeight(); -// int qrCodeY = (int) (backgroundHeight - qrCodeHeight / 2); + int qrCodeX = (backgroundImage.getWidth() - wh) / 2; + int qrCodeY = (int) ((backgroundImage.getHeight() - wh) * 0.6); // 绘制小程序码图像 - g2d.drawImage(qrCodeImage, qrCodeX, 1100, null); + g2d.drawImage(qrCodeImage, qrCodeX, qrCodeY, wh, wh, null); // 释放Graphics2D资源 g2d.dispose(); - // 将合并后的图像保存到文件(或根据需要执行其他操作) - file = new java.io.File(outputFilePath); - ImageIO.write(combinedImage, "png", file); - - String tempSave = outputFilePath; - String filePath = tempSave; - - file = new File(filePath); - if (!file.exists()) { - file.createNewFile(); - } - // 上传到阿里云 - DiskFileItemFactory factory = new DiskFileItemFactory(16, null); - FileItem item = factory.createItem("File", "text/plain", true, file.getName()); - int bytesRead = 0; - byte[] buffer = new byte[8192]; - try { - FileInputStream fis = new FileInputStream(file); - OutputStream os = item.getOutputStream(); - while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) { - os.write(buffer, 0, bytesRead); - } - os.close(); - fis.close(); - } catch (IOException e) { - e.printStackTrace(); - } - MultipartFile mf = new CommonsMultipartFile(item); - String rul = this.uploadAliYunOss(mf); - - System.out.println("合并后的图像已保存到" + this.uploadAliYunOss(mf)); - - return rul; + // 将合并后的图像保存到临时文件 + file = File.createTempFile("combined_", ".png"); + ImageIO.write(backgroundImage, "png", file); + // 上传到阿里云OSS +// return this.uploadAliYunOss(Files.readAllBytes(file.toPath()), file.getName()); + return Files.readAllBytes(file.toPath()); } catch (Exception e) { - e.printStackTrace(); + log.error("生成合并图片失败", e); + throw new RuntimeException("生成合并图片失败", e); } finally { - //删除文件 - if (file.exists()) { + // 删除临时文件 + if (file != null && file.exists()) { file.delete(); } } - return null; } @@ -1294,29 +1330,41 @@ public class AppletIndexServiceImpl implements AppletIndexService { return map.get("access_token"); } /** - * 上传文件至阿里云oss - * - * @return + * 上传文件至阿里云oss - 优化版 + * 直接使用字节数组上传,减少文件IO操作 + * + * @return 上传后的文件路径 */ - private String uploadAliYunOss(MultipartFile mf) throws Exception { + private String uploadAliYunOss(byte[] content, String fileName) throws Exception { String uploadFile = "WxCodeFile"; - String fileName = new StringBuffer(mf.getOriginalFilename()).append(".jpg").toString();// 获取文件名 - String dbpath = uploadFile + File.separator + fileName; - if (dbpath.contains("\\")) { - dbpath = dbpath.replace("\\", "/"); + String dbpath = uploadFile + "/" + fileName; + + // 创建OSSClient实例 + OSS ossClient = null; + try { + // 直接获取文件字节数组,避免额外的IO操作 + + // 创建OSS客户端 + ossClient = new OSSClientBuilder().build(endpoint, accessKey, secretKey); + + // 设置文件元数据 + com.aliyun.oss.model.ObjectMetadata metadata = new com.aliyun.oss.model.ObjectMetadata(); + metadata.setContentType("image/jpeg"); + metadata.setContentLength(content.length); + + // 上传字节数组 + ossClient.putObject(bucketName, dbpath, new ByteArrayInputStream(content), metadata); + + return dbpath; + } catch (Exception e) { + log.error("上传文件到阿里云OSS失败", e); + throw e; + } finally { + // 确保关闭OSS客户端 + if (ossClient != null) { + ossClient.shutdown(); + } } - String endpoint = this.endpoint; - String accessKey = this.accessKey; - String secretKey = this.secretKey; - // 创建OSSClient实例。 - OSS ossClient = new OSSClientBuilder().build(endpoint, accessKey, secretKey); - // 上传Byte数组。 - byte[] content = mf.getBytes(); - String bucketName = this.bucketName; - ossClient.putObject(bucketName, dbpath, new ByteArrayInputStream(content)); - // 关闭OSSClient。 - ossClient.shutdown(); - return dbpath; }