diff --git a/epdc-commons-tools/pom.xml b/epdc-commons-tools/pom.xml index cacc5eb..59f6795 100644 --- a/epdc-commons-tools/pom.xml +++ b/epdc-commons-tools/pom.xml @@ -22,6 +22,7 @@ 1.2.59 1.11.3 1.18.4 + 3.3.0 @@ -127,6 +128,11 @@ 0.7.0 compile + + com.google.zxing + core + ${zxing.version} + diff --git a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/constant/NumConstant.java b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/constant/NumConstant.java index 5b97c89..fd87daa 100644 --- a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/constant/NumConstant.java +++ b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/constant/NumConstant.java @@ -66,4 +66,6 @@ public interface NumConstant { int TWO_HUNDRED = 200; int ONE_THOUSAND = 1000; + int ONE_HUNDRED_EIGHTY = 180; + } diff --git a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/constant/PointsConstant.java b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/constant/PointsConstant.java index 03d6db0..c2bbaf0 100644 --- a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/constant/PointsConstant.java +++ b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/constant/PointsConstant.java @@ -15,4 +15,14 @@ public interface PointsConstant { * 手动调整积分动作编码 */ String behaviorCodeCode ="hand_regulation_behavior"; + + /** + * 积分规则编码-工作端-扫码兑换码-积分核销 + */ + String ruleWorkScanCodePointsVerification ="rule_points_exchange"; + + /** + * 积分动作编码-工作端-扫码兑换码-积分核销 + */ + String behaviorWorkScanCodePointsVerification ="points_exchange"; } diff --git a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/constant/StrConstant.java b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/constant/StrConstant.java index 9e4042c..566a31c 100644 --- a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/constant/StrConstant.java +++ b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/constant/StrConstant.java @@ -53,4 +53,8 @@ public interface StrConstant { * 下划线 */ String UNDERSCORE = "_"; + + String SUFFIX_IMG_PNG = "png"; + + String DOT = "."; } diff --git a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/enums/pointsenum/PointsOperationModeEnum.java b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/enums/pointsenum/PointsOperationModeEnum.java index c486cfb..fe2a26a 100644 --- a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/enums/pointsenum/PointsOperationModeEnum.java +++ b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/enums/pointsenum/PointsOperationModeEnum.java @@ -20,7 +20,12 @@ public enum PointsOperationModeEnum { /** * sys-系统操作 */ - OPERATION_MODE_SYS("sys"); + OPERATION_MODE_SYS("sys"), + + /** + * 工作端-扫描兑换码-积分核销 + */ + OPERATION_MODE_WORK_JFHX("work_jfhx"); private String operationMode; diff --git a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/FileUtils.java b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/FileUtils.java index 8300db1..a1b9123 100644 --- a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/FileUtils.java +++ b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/FileUtils.java @@ -1,10 +1,14 @@ package com.elink.esua.epdc.commons.tools.utils; import com.elink.esua.epdc.commons.tools.constant.NumConstant; +import org.apache.commons.lang3.StringUtils; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; +import java.io.IOException; /** * 文件操作工具 @@ -73,4 +77,26 @@ public class FileUtils { path.delete(); } } + + /** + * BufferedImage文件转为byte[] + * + * @param bImage 图片 + * @param formatName 格式 e.g. png + * @return byte[] + * @author work@yujt.net.cn + * @date 2020/8/7 13:30 + */ + public static byte[] imageToBytes(BufferedImage bImage, String formatName) { + if (null == bImage || StringUtils.isBlank(formatName)) { + return null; + } + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + ImageIO.write(bImage, formatName, out); + } catch (IOException e) { + //log.error(e.getMessage()); + } + return out.toByteArray(); + } } diff --git a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/QrCodeUtils.java b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/QrCodeUtils.java new file mode 100644 index 0000000..89f18cf --- /dev/null +++ b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/QrCodeUtils.java @@ -0,0 +1,224 @@ +package com.elink.esua.epdc.commons.tools.utils; + +import com.elink.esua.epdc.commons.tools.constant.StrConstant; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; +import com.google.zxing.MultiFormatWriter; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.CharEncoding; +import org.apache.commons.lang3.StringUtils; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.util.Hashtable; + +/** + * 二维码工具类 + * + * @author yujintao + * @date 2018/11/12 14:49 + */ +@Slf4j +public class QrCodeUtils { + + /** + * 二维码尺寸 + */ + private static final int QRCODE_SIZE = 800; + + /** + * 生成二维码图片,并转为byte[] + * + * @param content 二维码内的信息 + * @param imgPath logo地址 + * @param needCompress 是否压缩logo + * @return java.awt.image.BufferedImage + * @author work@yujt.net.cn + * @date 2020/8/7 10:58 + */ + public static byte[] encodeByByte(String content, String imgPath, boolean needCompress) { + return FileUtils.imageToBytes(encodeByImage(content, imgPath, needCompress), StrConstant.SUFFIX_IMG_PNG); + } + + /** + * 生成二维码图片 + * + * @param content 二维码内的信息 + * @param imgPath logo地址 + * @param needCompress 是否压缩logo + * @return java.awt.image.BufferedImage + * @author work@yujt.net.cn + * @date 2020/8/7 10:58 + */ + public static BufferedImage encodeByImage(String content, String imgPath, boolean needCompress) { + BufferedImage image = null; + try { + image = QrCodeUtils.createImage(content, imgPath, needCompress); + } catch (Exception e) { + log.error("创建二维码失败,\n content={} \n imagePath={}", content, imgPath); + } + return image; + } + + + /** + * 生成二维码(内嵌LOGO),选择是否压缩logo,直接存入指定文件目录 + * + * @param content 内容 + * @param imgPath LOGO地址 + * @param destPath 存放目录 + * @param needCompress 是否压缩LOGO + * @throws Exception + */ + public static void encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception { + BufferedImage image = QrCodeUtils.createImage(content, imgPath, needCompress); + mkdirs(destPath); + ImageIO.write(image, StrConstant.SUFFIX_IMG_PNG, new File(destPath)); + } + + /** + * 生成二维码(内嵌LOGO),不压缩logo,直接存入指定目录 + * + * @param content 内容 + * @param imgPath LOGO地址 + * @param destPath 存储地址 + * @throws Exception + */ + public static void encode(String content, String imgPath, String destPath) throws Exception { + QrCodeUtils.encode(content, imgPath, destPath, false); + } + + /** + * 生成二维码,不插入logo + * + * @param content 内容 + * @param destPath 存储地址 + * @throws Exception + */ + public static void encode(String content, String destPath) throws Exception { + QrCodeUtils.encode(content, null, destPath, false); + } + + /** + * 生成二维码(内嵌LOGO) + * + * @param content 内容 + * @param imgPath LOGO地址 + * @param output 输出流 + * @param needCompress 是否压缩LOGO + * @throws Exception + */ + public static void encode(String content, String imgPath, OutputStream output, boolean needCompress) + throws Exception { + BufferedImage image = QrCodeUtils.createImage(content, imgPath, needCompress); + ImageIO.write(image, StrConstant.SUFFIX_IMG_PNG, output); + } + + /** + * 生成二维码 + * + * @param content 内容 + * @param output 输出流 + * @throws Exception + */ + public static void encode(String content, OutputStream output) throws Exception { + QrCodeUtils.encode(content, null, output, false); + } + + private static BufferedImage createImage(String content, String imgPath, boolean needCompress) throws Exception { + Hashtable hints = new Hashtable(); + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); + hints.put(EncodeHintType.CHARACTER_SET, CharEncoding.UTF_8); + hints.put(EncodeHintType.MARGIN, 1); + BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, + hints); + int width = bitMatrix.getWidth(); + int height = bitMatrix.getHeight(); + 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, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); + } + } + if (StringUtils.isBlank(imgPath)) { + return image; + } + // 插入logo图片 + QrCodeUtils.insertImage(image, imgPath, needCompress); + return image; + } + + /** + * 插入LOGO + * + * @param source 二维码图片 + * @param imgPath LOGO图片地址 + * @param needCompress 是否压缩 + * @throws Exception + */ + private static void insertImage(BufferedImage source, String imgPath, boolean needCompress) throws Exception { + + URL url = new URL(imgPath); + InputStream is = url.openConnection().getInputStream(); + + Image src = ImageIO.read(is); + int width = src.getWidth(null); + int height = src.getHeight(null); + // 压缩LOGO + if (needCompress) { + // 限制最大LOGO宽度 + int maxWidth = QRCODE_SIZE / 4; + // 限制最大LOGO高度 + int maxHeight = QRCODE_SIZE / 4; + + if (width > maxWidth) { + width = maxWidth; + } + if (height > maxHeight) { + height = maxHeight; + } + Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH); + BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = tag.getGraphics(); + // 绘制缩小后的图 + g.drawImage(image, 0, 0, null); + g.dispose(); + src = image; + } + // 插入LOGO + Graphics2D graph = source.createGraphics(); + int x = (QRCODE_SIZE - width) / 2; + int y = (QRCODE_SIZE - height) / 2; + graph.drawImage(src, x, y, width, height, null); + Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6); + graph.setStroke(new BasicStroke(3f)); + graph.draw(shape); + graph.dispose(); + } + + + /** + * 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常) + * + * @param destPath 存放目录 + * @author lanyuan Email: mmm333zzz520@163.com + * @date 2013-12-11 上午10:16:36 + */ + private static void mkdirs(String destPath) { + File file = new File(destPath); + // 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常) + if (!file.exists() && !file.isDirectory()) { + file.mkdirs(); + } + } + + +}