Commit bfe16c51 authored by daniel's avatar daniel

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

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