This commit is contained in:
张良(004796)
2024-04-25 20:10:03 +08:00
parent eabb766e11
commit 19139ae642
8 changed files with 494 additions and 0 deletions

View File

@@ -53,5 +53,15 @@
<artifactId>aliyun-java-sdk-core</artifactId> <artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.0</version> <version>4.5.0</version>
</dependency> </dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.4.1</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -54,6 +54,9 @@ public class UserExtend implements Serializable {
*/ */
private BigDecimal withdrawTotal; private BigDecimal withdrawTotal;
private String qrUrl;
private String shareUrl;
private LocalDateTime createTime; private LocalDateTime createTime;
private LocalDateTime updateTime; private LocalDateTime updateTime;

View File

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

View File

@@ -43,4 +43,5 @@ public interface UserExtendService extends IService<UserExtend> {
UserExtend getByUserId(Long id); UserExtend getByUserId(Long id);
UserExtend getByUserCode(String usercode);
} }

View File

@@ -188,5 +188,9 @@ public class UserExtendServiceImpl extends ServiceImpl<UserExtendMapper,UserExte
public UserExtend getByUserId(Long userId) { public UserExtend getByUserId(Long userId) {
return this.getOne(Wrappers.lambdaQuery(UserExtend.class).eq(UserExtend::getUserId, userId).last("limit 1")); return this.getOne(Wrappers.lambdaQuery(UserExtend.class).eq(UserExtend::getUserId, userId).last("limit 1"));
} }
@Override
public UserExtend getByUserCode(String usercode) {
return this.getOne(Wrappers.lambdaQuery(UserExtend.class).eq(UserExtend::getUsercode, usercode).last("limit 1"));
}
} }

View File

@@ -0,0 +1,31 @@
package com.ruoyi.xq.util;
import org.springframework.util.ResourceUtils;
import java.io.File;
import java.io.FileNotFoundException;
public class FileUtils {
private final static String TEMP_PATH = "/temp";
public static String getTempFile() throws FileNotFoundException {
File path = new File(ResourceUtils.getURL("classpath:").getPath());
if (!path.exists()) {
path = new File("");
}
File tempLocaltion = new File(path.getAbsolutePath() + TEMP_PATH);
if (!tempLocaltion.exists()) {
tempLocaltion.mkdirs();
}
return tempLocaltion.getAbsolutePath();
}
public static String getRootFIle() throws FileNotFoundException {
File path = new File(ResourceUtils.getURL("classpath:").getPath());
if (!path.exists()) {
path = new File("");
}
return path.getAbsolutePath();
}
}

View File

@@ -0,0 +1,233 @@
package com.ruoyi.xq.util;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
/**
*
* 类名称ImageUtil
* 类描述: 图片操作工具类 把图片加载到内存,给图片 贴图,给图片添加文字
* 创建时间2021年7月30日 上午10:27:13
* @version
*/
public class ImageUtil {
private final static String BACK_IMAGE_PATH = "/home/server/cai/images/share_back.png";
// 1260 2100
public static void main(String[] args) throws IOException {
String backImagePath = "d:\\Users\\004796\\桌面\\file\\推广底图.png";
String smallPath = "d:\\Users\\004796\\桌面\\file\\qrcode.png";
String outPath = "d:\\Users\\004796\\桌面\\file\\qrcode12333.png";
Font font = new Font("宋体",Font.PLAIN, 35);
Font nicknameFont = new Font("宋体",Font.BOLD, 45);
Color color = new Color(255,255,255);
// new ImageUtil().mergeImage(backImagePath, smallPath, outPath, "430", "1600", 400, 400);
// new ImageUtil().drawTextInImg(backImagePath, "张女士", outPath, nicknameFont, 30, 80, color, 800, 30, true, 0.9);
String text = "邀请您注册遇见良缘";
int row = new ImageUtil().drawTextInImg(backImagePath, text, outPath, font, 30, 40, color, 440, 30, true, 0.9);
}
public static File genShareFile(String usercode,String qrPath) throws IOException {
String tempFile = FileUtils.getTempFile();
File parentFile = new File(new File(tempFile),usercode);
if(!parentFile.exists()){
parentFile.mkdirs();
}
String fileName = System.currentTimeMillis() + ".png";
File outFile = new File(parentFile,fileName);
new ImageUtil().mergeImage(BACK_IMAGE_PATH, qrPath, outFile.getAbsolutePath(), "430", "1600", 400, 400);
return outFile;
}
/**
* 解析本地图片或者http网络图片并把图片加载到缓冲区
* @param path 图片路径本地路径或者网络图片http访问路径
* @throws IOException 抛出异常
*/
public static BufferedImage imageIoRead(String path) throws IOException {
BufferedImage bufferedImage;
if(path.contains("http")){
//网络图片
bufferedImage = ImageIO.read(new URL(path));
}else{
//本地图片
bufferedImage = ImageIO.read(new File(path));
}
return bufferedImage;
}
/**
* 给一张图片贴 图片,并生成新图片
* @param bigPath 底图路径
* @param smallPath 要贴的图片路径
* @param outPath 合成输出图片路径
* @param x 贴图的位置
* @param y 贴图的位置
* @param smallWidth 要贴的图片宽度
* @param smallHeight 要贴的图片高度
* @throws IOException 抛出io异常
*/
public void mergeImage( String bigPath,
String smallPath,
String outPath,
String x,
String y,
int smallWidth,
int smallHeight ) throws IOException {
try {
//加载图片
BufferedImage small = imageIoRead(smallPath);
BufferedImage big = imageIoRead(bigPath);
//得到2d画笔对象
Graphics2D g = big.createGraphics();
float fx = Float.parseFloat(x);
float fy = Float.parseFloat(y);
int x_i = (int)fx;
int y_i = (int)fy;
g.drawImage(small, x_i, y_i,smallWidth,smallHeight, null);
g.dispose();
//输出图片
ImageIO.write(big, "png", new File(outPath));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 向画布上写多行文字文字,自动居中
* @param filePath 原图路径
* @param text 要添加的文字
* @param outPath 输出图片路径
* @param font 字体
* @param x 坐标X
* @param y 坐标y
* @param color 字体颜色
* @param fontheight 字体高度
* @param maxWeight 每行字体最大宽度
* @param center 是否居中
* @param rate 字体间距
* @return int 写了几行字
*/
public int drawTextInImg( String filePath,
String text,
String outPath,
Font font,
int x,
int y,
Color color,
int maxWeight,
int fontheight,
boolean center,
double rate) {
int row = 0;
try {
//图片加载到缓冲区
BufferedImage bimage = imageIoRead(filePath);
//得到2d画笔对象
Graphics2D g = bimage.createGraphics();
//设置填充颜色
g.setPaint(color);
//设置字体
g.setFont(font);
//调用写写文字方法
row = drawString(g,font,text, x, y,maxWeight,fontheight,center,rate);
g.dispose();
//输出图片
FileOutputStream out = new FileOutputStream(outPath);
ImageIO.write(bimage, "png", out);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
return row;
}
/**
* 写文字
* @param g 2d画笔对象
* @param font 字体
* @param text 要添加的文字
* @param x 坐标X
* @param y 坐标y
* @param maxWidth 每行字体最大宽度
* @param height 字体高度
* @param center 是否居中
* @param rate 字体间距
* @return int 写了几行字
*/
public int drawString( Graphics2D g ,
Font font ,
String text ,
int x ,
int y ,
int maxWidth,
int height,
boolean center,
double rate) {
int row = 1;
JLabel label = new JLabel(text);
label.setFont(font);
FontMetrics metrics = label.getFontMetrics(label.getFont());
int textH = height; //metrics.getHeight();
int textW = metrics.stringWidth(label.getText()); //字符串的宽
String tempText = text;
//如果字符串长度大于最大宽度,执行循环
while(textW > 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);
}
}
}

View File

@@ -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<EncodeHintType, Object> getHints(int hint) {
java.util.Map<EncodeHintType, Object> 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;
}
}