diff --git a/ruoyi-xq/pom.xml b/ruoyi-xq/pom.xml index c625d25..462f906 100644 --- a/ruoyi-xq/pom.xml +++ b/ruoyi-xq/pom.xml @@ -53,5 +53,15 @@ aliyun-java-sdk-core 4.5.0 + + com.google.zxing + core + 3.4.1 + + + com.google.zxing + javase + 3.4.1 + diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/domain/UserExtend.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/domain/UserExtend.java index ffc46b5..463adcd 100644 --- a/ruoyi-xq/src/main/java/com/ruoyi/xq/domain/UserExtend.java +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/domain/UserExtend.java @@ -54,6 +54,9 @@ public class UserExtend implements Serializable { */ private BigDecimal withdrawTotal; + private String qrUrl; + private String shareUrl; + private LocalDateTime createTime; private LocalDateTime updateTime; diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/manager/ShareManager.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/manager/ShareManager.java new file mode 100644 index 0000000..33009b1 --- /dev/null +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/manager/ShareManager.java @@ -0,0 +1,75 @@ +package com.ruoyi.xq.manager; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.domain.vo.SysOssVo; +import com.ruoyi.system.service.ISysOssService; +import com.ruoyi.xq.domain.UserExtend; +import com.ruoyi.xq.service.UserExtendService; +import com.ruoyi.xq.util.ImageUtil; +import com.ruoyi.xq.util.QrUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.io.File; + +@Component +@Slf4j +public class ShareManager { + private final static String login = "https://12903012.com"; + + @Autowired + private UserExtendService userExtendService; + @Autowired + private ISysOssService sysOssService; + + public String genQrCode(String usercode){ + UserExtend userExtend = userExtendService.getByUserCode(usercode); + if(userExtend == null){ + return null; + } + if(StringUtils.isNotEmpty(userExtend.getQrUrl())){ + return userExtend.getQrUrl(); + } + String url = login + "from=" + usercode; + try { + File file = QrUtils.generateQrCode(usercode, url); + SysOssVo oss = sysOssService.upload(file); + userExtendService.update(Wrappers.lambdaUpdate(UserExtend.class).eq(UserExtend::getId, userExtend.getId()) + .set(UserExtend::getQrUrl, oss.getUrl())); + return oss.getUrl(); + } catch (Exception e) { + log.error("生成QR二维码失败!", e); + return null; + } + } + + public String getOrGenShareUrl(String usercode) { + UserExtend userExtend = userExtendService.getByUserCode(usercode); + if(userExtend == null){ + return null; + } + if(StringUtils.isNotEmpty(userExtend.getShareUrl())){ + return userExtend.getShareUrl(); + } + return genShareUrl(usercode); + } + + public String genShareUrl(String usercode){ + String qrUrl = genQrCode(usercode); + if(qrUrl == null){ + return null; + } + try { + File file = ImageUtil.genShareFile(usercode, qrUrl); + SysOssVo oss = sysOssService.upload(file); + userExtendService.update(Wrappers.lambdaUpdate(UserExtend.class).eq(UserExtend::getUsercode, usercode) + .set(UserExtend::getShareUrl, oss.getUrl())); + return oss.getUrl(); + }catch (Exception e){ + log.error("生成分享二维码失败!", e); + return null; + } + } +} diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/service/UserExtendService.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/service/UserExtendService.java index 2345edb..7790836 100644 --- a/ruoyi-xq/src/main/java/com/ruoyi/xq/service/UserExtendService.java +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/service/UserExtendService.java @@ -43,4 +43,5 @@ public interface UserExtendService extends IService { UserExtend getByUserId(Long id); + UserExtend getByUserCode(String usercode); } diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/service/impl/UserExtendServiceImpl.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/service/impl/UserExtendServiceImpl.java index 6c0fae2..ea86a7d 100644 --- a/ruoyi-xq/src/main/java/com/ruoyi/xq/service/impl/UserExtendServiceImpl.java +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/service/impl/UserExtendServiceImpl.java @@ -188,5 +188,9 @@ public class UserExtendServiceImpl extends ServiceImpl maxWidth) { + int n = textW / maxWidth; + int subPos = tempText.length() / n; + String drawText = tempText.substring(0 , subPos); + int subTxtW = metrics.stringWidth(drawText); + while(subTxtW > maxWidth) { + subPos--; + drawText = tempText.substring(0 , subPos); + subTxtW = metrics.stringWidth(drawText); + } + //g.drawString(drawText, x, y); //不调整字体间距 + MyDrawString(drawText , x , y, rate, g); + y += textH; + textW = textW - subTxtW; + tempText = tempText.substring(subPos); + row++; + } + //居中 + if(center) { + x = x + (maxWidth - textW) / 2; + } + //g.drawString(tempText, x, y); //不调整字体间距 + MyDrawString(tempText , x , y, rate, g); + return row; + } + + /** + * 一个字一个字写,控制字体间距 + * @param str 要添加的文字 + * @param x 坐标x + * @param y 坐标y + * @param rate 字体间距 + * @param g 画笔 + */ + public void MyDrawString(String str, int x, int y, double rate, Graphics2D g){ + String tempStr= ""; + int orgStringWight = g.getFontMetrics().stringWidth(str); + int orgStringLength = str.length(); + int tempx=x; + int tempy=y; + while(str.length()>0) + { + tempStr=str.substring(0, 1); + str=str.substring(1, str.length()); + g.drawString(tempStr, tempx, tempy); + tempx=(int)(tempx+(double)orgStringWight/(double)orgStringLength*rate); + } + } + +} + diff --git a/ruoyi-xq/src/main/java/com/ruoyi/xq/util/QrUtils.java b/ruoyi-xq/src/main/java/com/ruoyi/xq/util/QrUtils.java new file mode 100644 index 0000000..33d9ad6 --- /dev/null +++ b/ruoyi-xq/src/main/java/com/ruoyi/xq/util/QrUtils.java @@ -0,0 +1,137 @@ +package com.ruoyi.xq.util; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.WriterException; +import com.google.zxing.client.j2se.MatrixToImageWriter; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import lombok.Data; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.Path; + +@Data +public class QrUtils { + private static final int QR_CODE_SIZE = 500; + + public static void main(String[] args) throws WriterException, IOException { + String text = "Hello, World!"; + QRCodeWriter qrCodeWriter = new QRCodeWriter(); + BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE,getHints(1)); + Path path = FileSystems.getDefault().getPath("qrcode.png"); + MatrixToImageWriter.writeToPath(bitMatrix, "PNG", path); + System.out.println("二维码已生成:" + path); + } + + public static File generateQrCode(String usercode,String url) throws WriterException, IOException { + String tempFile = FileUtils.getTempFile(); + File parentFile = new File(tempFile, "qr"); + if(!parentFile.exists()){ + parentFile.mkdirs(); + } + File qrFile = new File(parentFile, usercode + ".png"); + QRCodeWriter qrCodeWriter = new QRCodeWriter(); + BitMatrix bitMatrix = qrCodeWriter.encode(url, BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE,getHints(1)); + MatrixToImageWriter.writeToPath(bitMatrix, "PNG", qrFile.toPath()); + return qrFile; + } + + /** + * 二维码生成 + * 该方法可以有效去除生成的二维码的多余空白 + * @param url 二维码跳转路径 + * @param height 高 + * @param width 宽 + * @param imageType 图片格式 + * @param hint 留白度 + */ + /*public static String generateQRCodeFile(String url, int height, int width, String imageType, int hint){ + try { + //生成二维码 + BitMatrix matrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, width, height, getHints(hint)); + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + image.setRGB(x, y, matrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + //去除多余空白 + BufferedImage distinctImage = removeWhiteBorder(image); + int disHeight = distinctImage.getHeight(); + int disWidth = distinctImage.getWidth(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + //去除空白后可能导致二维码图片变小,所以放大二维码 + if(disHeight < height || disWidth < width){ + BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics2D graphics = newImage.createGraphics(); + AffineTransform af = new AffineTransform(); + af.scale(width * 1.0 / disWidth, height * 1.0 / disHeight); + graphics.drawImage(distinctImage, af, null); + graphics.dispose(); + ImageIO.write(newImage, imageType, outputStream); + }else{ + ImageIO.write(distinctImage, imageType, outputStream); + } + ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); + FileItem fileItem = MtgiCommUtil.createFileItem(inputStream, "file." + imageType); + //上传到文件服务 + FileUtil fileUtil = SpringUtil.getBean(FileUtil.class); + return fileUtil.getFileId(fileItem); + } catch (Exception e) { + throw new RuntimeException(e); + } + }*/ + /** + * Zxing二维码参数设置 + * @param hint 白边大小 + */ + private static java.util.Map getHints(int hint) { + java.util.Map hints = new java.util.HashMap<>(); + hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); + hints.put(EncodeHintType.ERROR_CORRECTION, com.google.zxing.qrcode.decoder.ErrorCorrectionLevel.H); + hints.put(EncodeHintType.MARGIN, hint); + return hints; + } + + /** + * 去除二维码图像多余的白边 + */ + private static BufferedImage removeWhiteBorder(BufferedImage image) { + int width = image.getWidth(); + int height = image.getHeight(); + int leftMost = width; + int rightMost = 0; + int topMost = height; + int bottomMost = 0; + + // 扫描每一行和每一列,找到有色块的最小矩形 + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + if (image.getRGB(x, y) != -1) { // 非白色 + leftMost = Math.min(leftMost, x); + rightMost = Math.max(rightMost, x); + topMost = Math.min(topMost, y); + bottomMost = Math.max(bottomMost, y); + } + } + } + + // 计算出最小矩形的宽和高 + int newWidth = rightMost - leftMost + 1; + int newHeight = bottomMost - topMost + 1; + + // 创建一个新图像并复制原图像的最小矩形部分 + BufferedImage newImage = new BufferedImage(newWidth, newHeight, image.getType()); + for (int y = topMost; y <= bottomMost; y++) { + for (int x = leftMost; x <= rightMost; x++) { + newImage.setRGB(x - leftMost, y - topMost, image.getRGB(x, y)); + } + } + + return newImage; + } +}