Commit bfe16c51 authored by daniel's avatar daniel

feat(gk): WeChat二维码优化,处理二维码无法生成的问题

parent 5cb17ca3
......@@ -8,3 +8,4 @@ ai.md
Makefile
.DS_Store
.trae
.claude/
......@@ -26,17 +26,24 @@ public class GlobalExceptionHandler {
private String maxFileSize;
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResultBean<?> handleMethodArgumentNotValid(MethodArgumentNotValidException e) {
public ResultBean<?> handleMethodArgumentNotValid(MethodArgumentNotValidException e, HttpServletRequest request) {
String msg = Objects.requireNonNull(
e.getBindingResult().getFieldError()
).getDefaultMessage();
String uri = request.getRequestURI();
String ip = getClientIp(request);
log.info("MethodArgumentNotValid | URI: {} | IP: {} | Message: {}", uri, ip, msg);
return ResultBean.fail(msg);
}
@ResponseBody
@ExceptionHandler(value = Exception.class)
public ResultBean<?> errorHandler(Exception ex) {
log.info("exception from GlobalExceptionHandler : {} {}",ex.getClass(),ex.getMessage());
public ResultBean<?> errorHandler(Exception ex, HttpServletRequest request) {
String uri = request.getRequestURI();
String method = request.getMethod();
String ip = getClientIp(request);
log.info("exception from GlobalExceptionHandler : {} {} | URI: {} | Method: {} | IP: {}",
ex.getClass(), ex.getMessage(), uri, method, ip);
return ResultBean.fail(ex.getMessage());
}
......
......@@ -51,31 +51,32 @@ public class ResourcesController {
public void img(@PathVariable("cmptid") Integer cmptid, HttpServletResponse response) throws IOException {
JSONObject obj = new JSONObject();
obj.put("scene", "raceId=" + cmptid);
// 修改为小程序页面路径 by 2025-06-12
obj.put("page", "pages/race/raceHome");
obj.put("width", "1280");
obj.put("check_path", false);
String partnerId = cmptService.getPartnerId(cmptid);
String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=";
try {
// 重新获取小程序access_token
String accessToken = wechatMiniService.getMicroAccessToken(partnerId);
url += accessToken;
ResponseEntity<org.springframework.core.io.Resource> resourceResponseEntity = restTemplate.postForEntity(url, obj.toString(), org.springframework.core.io.Resource.class);
ResponseEntity<byte[]> resourceResponseEntity = restTemplate.postForEntity(url, obj.toString(), byte[].class);
byte[] imageBytes = resourceResponseEntity.getBody();
ServletOutputStream outputStream = response.getOutputStream();
org.springframework.core.io.Resource body = resourceResponseEntity.getBody();
Cmpt cmpt = cmptService.queryCmptBycmptId(cmptid);
log.info("===== 获取小程序二维码/img/{cmptid}, accessToken:" + accessToken + ", cmptLogo:" + cmpt.getLogo());
if (!StringUtils.isEmpty(cmpt.getLogo())) {
BufferedImage bg = ImageIO.read(resourceResponseEntity.getBody().getInputStream());
BufferedImage qr = ImageIO.read(new URL(cmpt.getLogo()));
log.info("===== 获取小程序二维码/img/{}, accessToken:{}, cmptLogo:{}", cmptid, accessToken, cmpt.getLogo());
response.setContentType("image/jpeg");
BufferedImage bg = ImageIO.read(new java.io.ByteArrayInputStream(imageBytes));
BufferedImage qr = !StringUtils.isEmpty(cmpt.getLogo()) ? ImageIO.read(new URL(cmpt.getLogo())) : null;
overlapImageHD(bg, qr, response);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().contains("Broken pipe")) {
log.warn("=====获取小程序二维码客户端断开连接: cmptid={}", cmptid);
} else {
writeBytes(body.getInputStream(), outputStream);
log.error("=====获取小程序二维码IO异常: {}", e.getMessage());
}
} catch (Exception e) {
log.info("=====获取小程序二维码异常: "+e.getMessage());
log.error("=====获取小程序二维码异常: {}", e.getMessage());
wechatMiniService.resetMicroAccessToken(partnerId);
}
}
......@@ -88,27 +89,34 @@ public class ResourcesController {
response.addHeader("Content-Disposition", "attachment; filename=qrcode.jpg");
JSONObject obj = new JSONObject();
obj.put("scene", "raceId=" + cmptid);
// 修改为小程序页面路径 by 2025-06-12
obj.put("page", page);
obj.put("width", "1280");
obj.put("check_path", false);
String partnerId = cmptService.getPartnerId(cmptid);
try {
// 重新获取小程序access_token
String accessToken = wechatMiniService.getMicroAccessToken(partnerId);
ResponseEntity<org.springframework.core.io.Resource> resourceResponseEntity = restTemplate.postForEntity(
"https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken , obj.toString(), org.springframework.core.io.Resource.class);
ResponseEntity<byte[]> resourceResponseEntity = restTemplate.postForEntity(
"https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken, obj.toString(), byte[].class);
byte[] imageBytes = resourceResponseEntity.getBody();
Cmpt cmpt = cmptService.queryCmptBycmptId(cmptid);
log.info("===== 下载小程序二维码/download/{cmptid}, accessToken:" + accessToken + ", cmptLogo:" + cmpt.getLogo());
if(resourceResponseEntity.getBody().getInputStream() != null){
BufferedImage bg = ImageIO.read(resourceResponseEntity.getBody().getInputStream());
BufferedImage qr = ImageIO.read(new URL(cmpt.getLogo()));
log.info("===== 下载小程序二维码/download/{}, accessToken:{}, cmptLogo:{}", cmptid, accessToken, cmpt.getLogo());
if (imageBytes != null && imageBytes.length > 0) {
BufferedImage bg = ImageIO.read(new java.io.ByteArrayInputStream(imageBytes));
BufferedImage qr = !StringUtils.isEmpty(cmpt.getLogo()) ? ImageIO.read(new URL(cmpt.getLogo())) : null;
overlapImageHDPlus(bg, qr, response);
}else{
log.info("=====获取小程序码为空:"+resourceResponseEntity.getBody().toString());
} else {
log.info("=====获取小程序码为空: cmptid={}", cmptid);
}
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().contains("Broken pipe")) {
log.warn("=====下载小程序二维码客户端断开连接: cmptid={}", cmptid);
} else {
log.error("=====下载小程序二维码IO异常: {}", e.getMessage());
}
} catch (Exception e) {
log.info("=====下载小程序二维码异常: "+e.getMessage());
log.error("=====下载小程序二维码异常: {}", e.getMessage());
wechatMiniService.resetMicroAccessToken(partnerId);
}
}
......@@ -116,17 +124,15 @@ public class ResourcesController {
// ... 已有代码 ...
public static String overlapImageHDPlus(BufferedImage bg, BufferedImage qrCodeIps, HttpServletResponse response) throws Exception {
// 进一步增大背景图片尺寸
BufferedImage background = resizeImageHighQuality(2400, 2400, bg);
// 进一步增大二维码图片尺寸
if (qrCodeIps != null) {
BufferedImage qrCode = resizeImageHighQuality(1120, 1120, qrCodeIps);
qrCode = converToRadius(qrCode, 1120, 1120);
qrCode.createGraphics().setBackground(Color.WHITE);
Graphics2D g = background.createGraphics();
// 调整二维码位置
g.drawImage(qrCode, 640, 640, qrCode.getWidth(), qrCode.getHeight(), null);
g.dispose();
}
ImageIO.write(background, "jpg", response.getOutputStream());
return null;
}
......@@ -150,32 +156,30 @@ public class ResourcesController {
return bufferedImage;
}
public static String overlapImage(BufferedImage bg, BufferedImage qrCodeIps, HttpServletResponse response)throws Exception {
//设置图片大小
public static String overlapImage(BufferedImage bg, BufferedImage qrCodeIps, HttpServletResponse response) throws Exception {
BufferedImage background = resizeImage(300, 300, bg);
if (qrCodeIps != null) {
BufferedImage qrCode = resizeImage(140, 140, qrCodeIps);
qrCode = converToRadius(qrCode,140,140);
qrCode = converToRadius(qrCode, 140, 140);
qrCode.createGraphics().setBackground(Color.WHITE);
Graphics2D g = background.createGraphics();
//在背景图片上添加二维码图片
g.drawImage(qrCode, 80, 80, qrCode.getWidth(), qrCode.getHeight(), null);
g.dispose();
}
ImageIO.write(background, "jpg", response.getOutputStream());
return null;
}
public static String overlapImageHD(BufferedImage bg, BufferedImage qrCodeIps, HttpServletResponse response) throws Exception{
//设置图片大小
public static String overlapImageHD(BufferedImage bg, BufferedImage qrCodeIps, HttpServletResponse response) throws Exception {
BufferedImage background = resizeImage(1200, 1200, bg);
if (qrCodeIps != null) {
BufferedImage qrCode = resizeImage(560, 560, qrCodeIps);
qrCode = converToRadius(qrCode,560,560);
qrCode = converToRadius(qrCode, 560, 560);
qrCode.createGraphics().setBackground(Color.WHITE);
Graphics2D g = background.createGraphics();
//在背景图片上添加二维码图片
g.drawImage(qrCode, 320, 320, qrCode.getWidth(), qrCode.getHeight(), null);
g.dispose();
}
ImageIO.write(background, "jpg", response.getOutputStream());
return null;
}
......
......@@ -59,6 +59,14 @@ public class LoginController {
@RequestMapping("login/{id}")
public ModelAndView login(@PathVariable("id") int id,HttpServletRequest request,ModelAndView mv){
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
log.info("login/{} | IP: {}", id, ip);
GeexekUser geexekUser = cmptMapper.getGeexekUser(id);
request.getSession().setAttribute("user",geexekUser);
request.getSession().setAttribute("yfb",true);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment