|
|
@@ -25,6 +25,7 @@ import org.dromara.common.json.utils.JsonUtils;
|
|
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
|
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
|
import org.dromara.common.redis.utils.RedisUtils;
|
|
|
+import org.dromara.system.controller.NumberController;
|
|
|
import org.dromara.system.domain.GameEvent;
|
|
|
import org.dromara.system.domain.bo.*;
|
|
|
import org.dromara.system.domain.constant.GameEventConstant;
|
|
|
@@ -117,6 +118,28 @@ public class GameEventServiceImpl implements IGameEventService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public Font loadCustomFont(String fontPath, int fontSize) {
|
|
|
+ Font simheiFont = null;
|
|
|
+ try {
|
|
|
+ // 从资源目录加载字体文件
|
|
|
+ try (InputStream is = NumberController.class.getClassLoader().getResourceAsStream("fonts/"+fontPath+".ttf")) {
|
|
|
+ if (is != null) {
|
|
|
+ simheiFont = Font.createFont(Font.TRUETYPE_FONT, is);
|
|
|
+ log.info("成功加载{}字体文件", fontPath);
|
|
|
+ } else {
|
|
|
+ log.warn("未找到字体文件: fonts/{}.ttf", fontPath);
|
|
|
+ return new Font("SimHei", Font.BOLD, fontSize);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 调整字体大小并返回
|
|
|
+ return simheiFont.deriveFont(Font.BOLD, fontSize);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("加载字体失败,使用系统默认字体", e);
|
|
|
+ return new Font("SimHei", Font.BOLD, fontSize);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// 预览框尺寸(固定)
|
|
|
private static final int previewWidth = 600;
|
|
|
private static final int previewHeight = 400;
|
|
|
@@ -770,28 +793,26 @@ public class GameEventServiceImpl implements IGameEventService {
|
|
|
private static byte[] generateQRCode(String data, int width, int height) throws Exception {
|
|
|
// 使用QRCodeWriter而不是MultiFormatWriter,以便更好地控制二维码生成
|
|
|
QRCodeWriter qrCodeWriter = new QRCodeWriter();
|
|
|
-
|
|
|
+
|
|
|
Map<EncodeHintType, Object> hints = new HashMap<>();
|
|
|
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
|
|
|
// 设置纠错级别为L(最小纠错,最大数据容量)
|
|
|
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
|
|
|
// 设置边距为0,确保二维码内容填满指定尺寸
|
|
|
hints.put(EncodeHintType.MARGIN, 0);
|
|
|
-
|
|
|
- // 计算合适的二维码版本,确保所有二维码使用相同的版本
|
|
|
- // 版本5对应37x37模块,足够容纳所有运动员信息
|
|
|
+
|
|
|
// 使用QRCodeWriter.encode方法直接生成指定尺寸的矩阵
|
|
|
BitMatrix matrix = qrCodeWriter.encode(
|
|
|
- data,
|
|
|
- BarcodeFormat.QR_CODE,
|
|
|
- width,
|
|
|
- height,
|
|
|
+ data,
|
|
|
+ BarcodeFormat.QR_CODE,
|
|
|
+ width,
|
|
|
+ height,
|
|
|
hints
|
|
|
);
|
|
|
-
|
|
|
+
|
|
|
// 创建最终尺寸的图像
|
|
|
BufferedImage qrImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
|
|
-
|
|
|
+
|
|
|
// 直接在最终尺寸的图像上绘制二维码数据
|
|
|
// 确保每个像素都被正确设置,避免缩放差异
|
|
|
for (int x = 0; x < width; x++) {
|
|
|
@@ -801,7 +822,7 @@ public class GameEventServiceImpl implements IGameEventService {
|
|
|
qrImage.setRGB(x, y, color);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 将图像写入ByteArrayOutputStream
|
|
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
|
ImageIO.write(qrImage, "png", out);
|
|
|
@@ -1195,13 +1216,15 @@ public class GameEventServiceImpl implements IGameEventService {
|
|
|
|
|
|
// 确保字体名称匹配系统可用字体
|
|
|
String fontName = bibParam.getFontName();
|
|
|
- if (fontName == null) {
|
|
|
- fontName = "SimHei";
|
|
|
- } else if ("simhei".equalsIgnoreCase(fontName)) {
|
|
|
- fontName = "SimHei";
|
|
|
+ Font font;
|
|
|
+ if (fontName == null || "simhei".equalsIgnoreCase(fontName) || "SimHei".equals(fontName)) {
|
|
|
+ // 如果指定了黑体或未指定字体,则使用自定义加载的黑体字体,确保线上环境字体一致
|
|
|
+ font = loadCustomFont("simhei", fontSize);
|
|
|
+ log.info("号码使用自定义黑体字体: {}", font);
|
|
|
+ } else {
|
|
|
+ font = loadCustomFont(fontName, fontSize);
|
|
|
+ log.info("号码使用自定义字体: {}", font);
|
|
|
}
|
|
|
-
|
|
|
- Font font = new Font(fontName, Font.BOLD, fontSize);
|
|
|
g2d.setFont(font);
|
|
|
|
|
|
// 设置颜色
|
|
|
@@ -1249,7 +1272,7 @@ public class GameEventServiceImpl implements IGameEventService {
|
|
|
scaledHeight = initialQrSize * 3;
|
|
|
log.info("使用默认二维码尺寸: {}x{}", scaledWidth, scaledHeight);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 直接使用最终尺寸生成二维码,避免二次缩放
|
|
|
byte[] qrCodeBytes = generateQRCode(qrData, scaledWidth, scaledHeight);
|
|
|
BufferedImage qrImage = ImageIO.read(new ByteArrayInputStream(qrCodeBytes));
|