Browse Source

修复获取个人二维码太长时间、背景没有二维码的bug

master
前端-胡立永 1 month ago
parent
commit
aae3307eb9
4 changed files with 181 additions and 114 deletions
  1. +15
    -0
      .gitignore
  2. +4
    -3
      module-common/src/main/java/org/jeecg/api/controller/AppletInfoController.java
  3. +3
    -0
      module-common/src/main/java/org/jeecg/api/service/AppletIndexService.java
  4. +159
    -111
      module-common/src/main/java/org/jeecg/api/service/impl/AppletIndexServiceImpl.java

+ 15
- 0
.gitignore View File

@ -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

+ 4
- 3
module-common/src/main/java/org/jeecg/api/controller/AppletInfoController.java View File

@ -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);
}
//获取购物车信息列表带分页


+ 3
- 0
module-common/src/main/java/org/jeecg/api/service/AppletIndexService.java View File

@ -98,6 +98,9 @@ public interface AppletIndexService {
//获取个人邀请码
Result<?> getInviteCode(String token);
//获取个人邀请码
byte[] getInviteCode2(String token);
//获取相关介绍
Result<?> getInfoIntroduce(String type);


+ 159
- 111
module-common/src/main/java/org/jeecg/api/service/impl/AppletIndexServiceImpl.java View File

@ -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<byte[]> 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<String, Object> 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<String, Object> 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<String, String> headers = new LinkedMultiValueMap<>();
org.springframework.http.HttpEntity requestEntity = new org.springframework.http.HttpEntity(JSON.toJSONString(param), headers);
ResponseEntity<byte[]> 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;
}


Loading…
Cancel
Save