diff --git a/blade-common/pom.xml b/blade-common/pom.xml index 4030f00a..168cae32 100644 --- a/blade-common/pom.xml +++ b/blade-common/pom.xml @@ -28,6 +28,24 @@ blade-core-auto provided + + + cn.hutool + hutool-all + 5.8.16 + + + com.google.zxing + core + 3.3.3 + + + com.google.zxing + javase + 3.3.3 + + + diff --git a/blade-common/src/main/java/org/springblade/common/utils/QRCodeUtil.java b/blade-common/src/main/java/org/springblade/common/utils/QRCodeUtil.java new file mode 100644 index 00000000..cc5541cf --- /dev/null +++ b/blade-common/src/main/java/org/springblade/common/utils/QRCodeUtil.java @@ -0,0 +1,213 @@ +package org.springblade.common.utils; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.MultiFormatWriter; +import com.google.zxing.WriterException; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springblade.common.constant.CommonConstant; +import org.springframework.util.StringUtils; +import sun.misc.BASE64Encoder; + +import javax.imageio.ImageIO; +import javax.servlet.http.HttpServletResponse; +import javax.swing.filechooser.FileSystemView; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * 二维码工具 + * @Author:debug (SteadyJack) + * @Link: weixin-> debug0868 qq-> 1948831260 + * @Date: 2020/11/16 22:38 + **/ +public class QRCodeUtil { + private static final Logger log= LoggerFactory.getLogger(QRCodeUtil.class); + + //CODE_WIDTH:二维码宽度,单位像素 + private static final int CODE_WIDTH = 100; + //CODE_HEIGHT:二维码高度,单位像素 + private static final int CODE_HEIGHT = 100; + //FRONT_COLOR:二维码前景色,0x000000 表示黑色 + private static final int FRONT_COLOR = 0x000000; + //BACKGROUND_COLOR:二维码背景色,0xFFFFFF 表示白色 + //演示用 16 进制表示,和前端页面 CSS 的取色是一样的,注意前后景颜色应该对比明显,如常见的黑白 + private static final int BACKGROUND_COLOR = 0xFFFFFF; + //默认生成二维码格式 + private static final String FileFormat="png"; + + private static final String path="qrCodeImg"; + + + /** + * 文件转换base64 + * @param filePath + * @return + */ + public static String getEmpAutograph(String filePath) { + String img = null; + if (StringUtils.isEmpty(filePath)) { + InputStream in = null; + byte[] picdata = null; + try { + in = new FileInputStream(filePath); + picdata = new byte[in.available()]; + in.read(picdata); + BASE64Encoder encoder = new BASE64Encoder(); + img = encoder.encode(picdata); + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return "data:image/png;base64," + img; + } + + public static String createCodeToFile(String content) { + try { + + String imgPath = CommonUtil.SYSTEMFILEPATH+"qrCodeImg/"; + File codeImgFileSaveDir = new File(imgPath); + //1. 使用UUID重新生成文件名,防止文件名称重复造成文件覆盖 + String fileName = UUID.randomUUID() + "." +FileFormat; + content = content.trim(); + if (codeImgFileSaveDir==null || codeImgFileSaveDir.isFile()) { + //二维码图片存在目录为空,默认放在桌面... + codeImgFileSaveDir = FileSystemView.getFileSystemView().getHomeDirectory(); + } + if (!codeImgFileSaveDir.exists()) { + //二维码图片存在目录不存在,开始创建... + codeImgFileSaveDir.mkdirs(); + } + //核心代码-生成二维码 + BufferedImage bufferedImage = getBufferedImage(content); + File codeImgFile = new File(codeImgFileSaveDir, fileName); + ImageIO.write(bufferedImage, FileFormat, codeImgFile); + fileName = imgPath+fileName; + return fileName; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * 条形码 + * @param content + * @return + */ + public static String createCodeToFileType(String content) { + try { + //getResource("/")等同于到resource文件夹下 + String imgPath = CommonUtil.SYSTEMFILEPATH+"qrCodeImg/"; + File codeImgFileSaveDir = new File(imgPath); + //1. 使用UUID重新生成文件名,防止文件名称重复造成文件覆盖 + String fileName = UUID.randomUUID() + "." +FileFormat; + content = content.trim(); + if (codeImgFileSaveDir==null || codeImgFileSaveDir.isFile()) { + //二维码图片存在目录为空,默认放在桌面... + codeImgFileSaveDir = FileSystemView.getFileSystemView().getHomeDirectory(); + } + if (!codeImgFileSaveDir.exists()) { + //二维码图片存在目录不存在,开始创建... + codeImgFileSaveDir.mkdirs(); + } + //核心代码-生成二维码 + BufferedImage bufferedImage = getBufferedImageMatrix(content); + File codeImgFile = new File(codeImgFileSaveDir, fileName); + ImageIO.write(bufferedImage, FileFormat, codeImgFile); + fileName = imgPath+fileName; + return fileName; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * 生成二维码并输出到输出流, 通常用于输出到网页上进行显示,输出到网页与输出到磁盘上的文件中,区别在于最后一句 ImageIO.write + * write(RenderedImage im,String formatName,File output):写到文件中 + * write(RenderedImage im,String formatName,OutputStream output):输出到输出流中 + * @param content :二维码内容 + */ +// OutputStream outputStream, + public static void createCodeToOutputStream(String content, HttpServletResponse response) throws WriterException, IOException { + if (StringUtils.isEmpty(content)) { + return; + } + content = content.trim(); + //核心代码-生成二维码 + BufferedImage bufferedImage = getBufferedImage(content); + //区别就是这一句,输出到输出流中,如果第三个参数是 File,则输出到文件中 + ImageIO.write(bufferedImage, FileFormat,response.getOutputStream()); + log.info("二维码图片生成到输出流成功..."); + } + + //核心代码-生成二维码 + public static BufferedImage getBufferedImage(String content) throws WriterException { + + //com.google.zxing.EncodeHintType:编码提示类型,枚举类型 + Map hints = new HashMap(); + + //EncodeHintType.CHARACTER_SET:设置字符编码类型 + hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); + + //EncodeHintType.ERROR_CORRECTION:设置误差校正 + //ErrorCorrectionLevel:误差校正等级,L = ~7% correction、M = ~15% correction、Q = ~25% correction、H = ~30% correction + //不设置时,默认为 L 等级,等级不一样,生成的图案不同,但扫描的结果是一样的 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); + + //EncodeHintType.MARGIN:设置二维码边距,单位像素,值越小,二维码距离四周越近 + hints.put(EncodeHintType.MARGIN, 0); + + MultiFormatWriter multiFormatWriter = new MultiFormatWriter(); + BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, CODE_WIDTH, CODE_HEIGHT, hints); + BufferedImage bufferedImage = new BufferedImage(CODE_WIDTH, CODE_HEIGHT, BufferedImage.TYPE_INT_BGR); + for (int x = 0; x < CODE_WIDTH; x++) { + for (int y = 0; y < CODE_HEIGHT; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? FRONT_COLOR : BACKGROUND_COLOR); + } + } + return bufferedImage; + } //核心代码-生成二维码 + public static BufferedImage getBufferedImageMatrix(String content) throws WriterException { + + //com.google.zxing.EncodeHintType:编码提示类型,枚举类型 + Map hints = new HashMap(); + + //EncodeHintType.CHARACTER_SET:设置字符编码类型 + hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); + + //EncodeHintType.ERROR_CORRECTION:设置误差校正 + //ErrorCorrectionLevel:误差校正等级,L = ~7% correction、M = ~15% correction、Q = ~25% correction、H = ~30% correction + //不设置时,默认为 L 等级,等级不一样,生成的图案不同,但扫描的结果是一样的 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); + + //EncodeHintType.MARGIN:设置二维码边距,单位像素,值越小,二维码距离四周越近 + hints.put(EncodeHintType.MARGIN, 1); + + MultiFormatWriter multiFormatWriter = new MultiFormatWriter(); + BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.CODE_128, 240, 30, hints); + BufferedImage bufferedImage = new BufferedImage(240, 30, BufferedImage.TYPE_INT_BGR); + for (int x = 0; x < 240; x++) { + for (int y = 0; y < 30; y++) { + bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? FRONT_COLOR : BACKGROUND_COLOR); + } + } + return bufferedImage; + } +} diff --git a/blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/AppPdaversionVO.java b/blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/AppPdaversionVO.java index 314d5283..35f788c1 100644 --- a/blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/AppPdaversionVO.java +++ b/blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/AppPdaversionVO.java @@ -37,13 +37,14 @@ import java.util.List; public class AppPdaversionVO extends PdaversionManageEntity { private static final long serialVersionUID = 1L; - - /** * 上传人 */ @ApiModelProperty(value = "上传人") private String createUserName; + @ApiModelProperty(value = "下载地址二维码") + private String downLoadUrlQrcode; + } diff --git a/blade-service/blade-system/src/main/java/org/springblade/system/service/impl/PdaversionManageServiceImpl.java b/blade-service/blade-system/src/main/java/org/springblade/system/service/impl/PdaversionManageServiceImpl.java index 924e6128..78fabb21 100644 --- a/blade-service/blade-system/src/main/java/org/springblade/system/service/impl/PdaversionManageServiceImpl.java +++ b/blade-service/blade-system/src/main/java/org/springblade/system/service/impl/PdaversionManageServiceImpl.java @@ -19,6 +19,7 @@ package org.springblade.system.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import lombok.AllArgsConstructor; +import org.springblade.common.utils.QRCodeUtil; import org.springblade.core.tenant.mp.TenantEntity; import org.springblade.core.tool.api.R; import org.springblade.system.dto.AppPdaversionDTO; @@ -130,6 +131,12 @@ public class PdaversionManageServiceImpl extends BaseServiceImpl